Type.registerNamespace('Yoshi.Classes');

////////////////////////////////////////////////////////////////////////////////
// IDataShort

IDataShort = function() { 
};
IDataShort.prototype = {
    get_data : null,
    set_data : null
}
IDataShort.registerInterface('IDataShort');


////////////////////////////////////////////////////////////////////////////////
// IDataStore

IDataStore = function() { 
};
IDataStore.prototype = {
    get_user : null,
    get_auth : null,
    authenticateAw : null,
    get_authenticated : null,
    getRecord : null,
    putRecord : null,
    renameRecord : null
}
IDataStore.registerInterface('IDataStore');


////////////////////////////////////////////////////////////////////////////////
// IPage

IPage = function() { 
};
IPage.prototype = {
    updatePage : null,
    focusEvent : null,
    isFocused : null,
    destroy : null
}
IPage.registerInterface('IPage');


////////////////////////////////////////////////////////////////////////////////
// IData

IData = function() { 
};
IData.prototype = {
    get_data : null,
    set_data : null,
    get_saved : null,
    set_saved : null,
    loadRecordAw : null,
    saveRecord : null,
    get_recordName : null,
    renameRecord : null
}
IData.registerInterface('IData');


////////////////////////////////////////////////////////////////////////////////
// FileManager

FileManager = function FileManager() {
}
FileManager.updateFileAw = function FileManager$updateFileAw(awp, parKey, rowKey, fnModify, fnComplete) {
    /// <param name="awp" type="Await">
    /// </param>
    /// <param name="parKey" type="String">
    /// </param>
    /// <param name="rowKey" type="String">
    /// </param>
    /// <param name="fnModify" type="System.Action`2">
    /// </param>
    /// <param name="fnComplete" type="Function">
    /// </param>
    fnComplete = fnComplete || Helpers.noOp;
    new Await().addAw(FileBlobBase.retrieveBlobStringAw, parKey, rowKey).handleDl(Exceptions.blobLoadError, function(aw) {
        Inform.error('Could not load {0}', Uri.join(parKey, rowKey));
        aw.set_result(null);
        aw.done();
    }).addDl(function(aw) {
        var content = (aw.get_result() != null) ? JSON.parse(aw.get_result()) : null;
        var passed = [content];
        fnModify(content, passed);
        var output = Rx.prettyJson(passed[0]);
        Uri.bumpVersion();
        new Await().addAw(FileBlobBase.storeBlobStringAw, { partitionKey: parKey, rowKey: rowKey, content: output, backup: true }).addFn(fnComplete).commit(aw);
    }).commit(awp);
}


////////////////////////////////////////////////////////////////////////////////
// ImageManager

ImageManager = function ImageManager() {
    ImageManager.initializeBase(this);
}
ImageManager.thumbToFullAw = function ImageManager$thumbToFullAw(awp, url) {
    /// <param name="awp" type="Await">
    /// </param>
    /// <param name="url" type="String">
    /// </param>
    awp.set_result(url);
    new Await().addAw(FileBlobBase.retrieveBlobAw, ThemeYoshi.imagesPartitionKey, ThemeYoshi.imagesRowKey).handleDl(Exceptions.blobLoadError, Await.finishAw).addDx(function(aw) {
        var imgs = aw.get_result() || {};
        var $dict1 = imgs;
        for (var $key2 in $dict1) {
            var p = { key: $key2, value: $dict1[$key2] };
            if (p.value.thumb !== url) {
                continue;
            }
            awp.set_result(p.value.path || p.value.source);
            return;
        }
    }).commit(awp);
}
ImageManager.updateImageDataAw = function ImageManager$updateImageDataAw(awp, url) {
    /// <param name="awp" type="Await">
    /// </param>
    /// <param name="url" type="String">
    /// </param>
    var ix = null;
    new Await().addDx(function() {
        ix = $("<img style='position:absolute;top:-50000px;'/>").attr('src', url).appendTo(document.body);
    }).waitDx(function() {
        return ix.height() > 0;
    }).addAw(FileManager.updateFileAw, ThemeYoshi.imagesPartitionKey, ThemeYoshi.imagesRowKey, function(imagesD, imagesO) {
        imagesD = imagesD || {};
        imagesO[0] = imagesD;
        var images = imagesD;
        var lurl = ThemeYoshi.localUrl(url);
        var id = lurl || url;
        var imi = images[id] || new ImageItem();
        if (lurl != null) {
            imi.path = lurl;
            imi.master = lurl;
            imi.source = lurl;
            imi.thumb = imi.thumb || ImageManager.createThumbnail(lurl.substr(ThemeBase.appUri.length + 1));
        }
        else {
            imi.source = url;
            imi.thumb = imi.thumb || ImageManager.createThumbnail(url);
        }
        imi.width = ix.width();
        imi.height = ix.height();
        images[id] = imi;
        ix.remove();
    }).commit(awp);
}
ImageManager.clearThumbsAw = function ImageManager$clearThumbsAw(awp) {
    /// <param name="awp" type="Await">
    /// </param>
    new Await().addAw(FileManager.updateFileAw, ThemeYoshi.imagesPartitionKey, ThemeYoshi.imagesRowKey, function(imagesD, imagesO) {
        imagesD = imagesD || {};
        imagesO[0] = imagesD;
        var images = imagesD;
        var $dict1 = images;
        for (var $key2 in $dict1) {
            var p = { key: $key2, value: $dict1[$key2] };
            if (p.value.thumb != null) {
                ImageManager.deleteImageAw(Await.get_asyncAw(), p.value.thumb);
                p.value.thumb = null;
            }
        }
    }).commit(awp);
}
ImageManager.deleteImageAw = function ImageManager$deleteImageAw(awp, url) {
    /// <param name="awp" type="Await">
    /// </param>
    /// <param name="url" type="String">
    /// </param>
    FileBlobBase.deleteItemAw(awp, Uri.front(url).substr(ThemeBase.appUri.length + 1), Uri.end(url));
}
ImageManager.createThumbnail = function ImageManager$createThumbnail(url) {
    /// <summary>
    /// Creates the thumbnail image on the server.
    /// </summary>
    /// <param name="url" type="String">
    /// The URL or file path
    /// </param>
    /// <returns type="String"></returns>
    var en = Uri.end(url);
    var name = Uri.join('pg/images', 'tn.' + ((Uri.isHttp(url)) ? Formulas.get_newId() + Uri.ext(en) : en));
    var options = {};
    options.url = Uri.join(ThemeBase.appUri, 'file.thumbnail.php');
    options.dataType = 'json';
    options.type = 'GET';
    options.data = { source: url, file: name, width: 100, password: FileBlobBase.password };
    options.success = function() {
    };
    options.error = function() {
    };
    $.ajax(options);
    return Uri.join(ThemeBase.appUri, name);
}


////////////////////////////////////////////////////////////////////////////////
// StaticBuild

StaticBuild = function StaticBuild() {
}
StaticBuild.LoadCssAw = function StaticBuild$LoadCssAw(awp, cssFiles) {
    /// <param name="awp" type="Await">
    /// </param>
    /// <param name="cssFiles" type="String">
    /// </param>
    if (!String.isNullOrEmpty(cssFiles)) {
        var libs = cssFiles.split(',');
        var awx = new Await();
        var $enum1 = ss.IEnumerator.getEnumerator(libs);
        while ($enum1.moveNext()) {
            var lib = $enum1.current;
            awx.loadCss(Uri.smart(lib));
        }
        awx.commit(awp);
    }
    else {
        awp.done();
    }
}
StaticBuild.LoadLibsAw = function StaticBuild$LoadLibsAw(awp, scripts) {
    /// <param name="awp" type="Await">
    /// </param>
    /// <param name="scripts" type="String">
    /// </param>
    if (!String.isNullOrEmpty(scripts)) {
        var libs = scripts.split(',');
        var awx = new Await();
        var $enum1 = ss.IEnumerator.getEnumerator(libs);
        while ($enum1.moveNext()) {
            var lib = $enum1.current;
            awx.loadScript(Uri.smart(lib));
        }
        awx.commit(awp);
    }
    else {
        awp.done();
    }
}
StaticBuild.BuildAction = function StaticBuild$BuildAction(action, libs, css) {
    /// <param name="action" type="String">
    /// </param>
    /// <param name="libs" type="String">
    /// </param>
    /// <param name="css" type="String">
    /// </param>
    if (!ThemeYoshi.pageDone) {
        window.setTimeout(function() {
            StaticBuild.BuildAction(action, libs, css);
        }, 13);
        return;
    }
    new Await().addAw(StaticBuild.LoadCssAw, css).addAw(StaticBuild.LoadLibsAw, libs).addDx(function() {
        if (!String.isNullOrEmpty(action)) {
            try {
                eval(action + '()');
            }
            catch (ex) {
                Inform.error('Slide build error: {0}', ex);
            }
        }
    }).commit();
}
StaticBuild.Tilt = function StaticBuild$Tilt(tilts) {
    /// <param name="tilts" type="Object">
    /// </param>
    var $dict1 = tilts;
    for (var $key2 in $dict1) {
        var p = { key: $key2, value: $dict1[$key2] };
        console.log(String.format('tilting {0} by {1}', p.key, p.value));
        $('#' + p.key).rotate({ angle: p.value });
    }
}
StaticBuild.Finish = function StaticBuild$Finish() {
    window.setTimeout(function() {
        $('#PageGigs').fadeIn(300);
    }, 50);
}


////////////////////////////////////////////////////////////////////////////////
// UriParse

UriParse = function UriParse() {
    /// <field name="_classActionRx" type="RegExp" static="true">
    /// </field>
    /// <field name="_unClassActionRx" type="RegExp" static="true">
    /// </field>
}
UriParse._unanchor = function UriParse$_unanchor(match, m1, m2) {
    /// <param name="match" type="String">
    /// </param>
    /// <param name="m1" type="String">
    /// </param>
    /// <param name="m2" type="String">
    /// </param>
    /// <returns type="String"></returns>
    var ot = m2.replace(/([\s\S]*?=[\s\S]*?$)|([^=]*$)/, function(x,x1,x2){return x1?'"'+jQuery.trim(x1)+'"':jQuery.trim(x2);});
    m1 = UriParse._unClassAction(m1) || ThemeYoshi.UnSmartUrl(m1);
    return '(( ' + ot + ((!String.isNullOrEmpty(m1)) ? ' = ' + m1 : '') + ' ))';
}
UriParse.parseAnchorsToEdit = function UriParse$parseAnchorsToEdit(ot) {
    /// <param name="ot" type="String">
    /// </param>
    /// <returns type="String"></returns>
    ot = ot.replace(/<a\s+.*?href="([^"]*)"[^>]*?>(.*?)<\/a>/gi, UriParse._unanchor);
    return ot;
}
UriParse._anchor = function UriParse$_anchor(match, nm, uri) {
    /// <param name="match" type="String">
    /// </param>
    /// <param name="nm" type="String">
    /// </param>
    /// <param name="uri" type="String">
    /// </param>
    /// <returns type="String"></returns>
    nm = nm.trim().replace(/^["']|["']$/g, '');
    var ca = UriParse._classAction(uri);
    if (ca != null) {
        return String.format("<a class=\"UserLink\" href=\"javascript:Master.DoMethod('{1}');\">{0}</a>", nm, ca);
    }
    var u = ThemeYoshi.SmartUrl(uri);
    if (ThemeYoshi.IsCurateUrl(u)) {
        return '<a class="UserLink" href="'+(u)+'">'+nm+'</a>';
    }
    return '<a class="UserLink" href="'+(u)+'" target="_blank">'+nm+'</a>';
}
UriParse._classAction = function UriParse$_classAction(uri) {
    /// <param name="uri" type="String">
    /// </param>
    /// <returns type="String"></returns>
    UriParse._classActionRx.lastIndex = 0;
    var mx = UriParse._classActionRx.exec(uri);
    return (mx != null) ? mx[1].trim() : null;
}
UriParse._unClassAction = function UriParse$_unClassAction(uri) {
    /// <param name="uri" type="String">
    /// </param>
    /// <returns type="String"></returns>
    UriParse._unClassActionRx.lastIndex = 0;
    var mx = UriParse._unClassActionRx.exec(uri);
    return (mx != null) ? String.format('method:{0}', mx[1].trim()) : null;
}
UriParse.parseEditToAnchors = function UriParse$parseEditToAnchors(ot) {
    /// <param name="ot" type="String">
    /// </param>
    /// <returns type="String"></returns>
    ot = ot.replace(/\(\(\s*?("[^"\\]*(?:\\[\s\S][^"=\\]*)*"|'[^'\\]*(?:\\[\s\S][^'\\]*)*'|[^="']+?)\s*(?:=\s*([\s\S]*?)\s*\)\)|\s*\)\))/gm, UriParse._anchor);
    return ot;
}


////////////////////////////////////////////////////////////////////////////////
// PagesD

PagesD = function PagesD() {
    /// <field name="pages" type="Object">
    /// </field>
}
PagesD.prototype = {
    pages: null
}


////////////////////////////////////////////////////////////////////////////////
// PageD

PageD = function PageD() {
    /// <field name="Admin" type="Boolean">
    /// </field>
    /// <field name="Class" type="String">
    /// </field>
    /// <field name="Face" type="String">
    /// </field>
    /// <field name="Name" type="String">
    /// </field>
    /// <field name="Tests" type="String">
    /// </field>
    /// <field name="Title" type="String">
    /// </field>
    /// <field name="Visible" type="Boolean">
    /// </field>
}
PageD.prototype = {
    Admin: false,
    Class: null,
    Face: null,
    Name: null,
    Tests: null,
    Title: null,
    Visible: false
}


////////////////////////////////////////////////////////////////////////////////
// FeedItem

FeedItem = function FeedItem(categoryIn, messageIn) {
    /// <param name="categoryIn" type="String">
    /// </param>
    /// <param name="messageIn" type="String">
    /// </param>
    /// <field name="id" type="String">
    /// </field>
    /// <field name="category" type="String">
    /// </field>
    /// <field name="message" type="String">
    /// </field>
    /// <field name="hasComments" type="Boolean">
    /// </field>
    /// <field name="createTime" type="Number" integer="true">
    /// </field>
    /// <field name="unread" type="Boolean">
    /// </field>
    /// <field name="link" type="String">
    /// </field>
    /// <field name="textCategory" type="String" static="true">
    /// </field>
    this.id = Formulas.get_newId();
    this.category = categoryIn;
    this.message = messageIn;
    this.createTime = new Date().getTime();
    this.unread = true;
}
FeedItem.prototype = {
    id: null,
    category: null,
    message: null,
    hasComments: false,
    createTime: 0,
    unread: false,
    link: null
}


////////////////////////////////////////////////////////////////////////////////
// CommentItem

CommentItem = function CommentItem(blobIn) {
    /// <param name="blobIn" type="String">
    /// </param>
    /// <field name="id" type="String">
    /// </field>
    /// <field name="byId" type="String">
    /// </field>
    /// <field name="blob" type="String">
    /// </field>
    /// <field name="hasComments" type="Boolean">
    /// </field>
    /// <field name="createTime" type="Number" integer="true">
    /// </field>
    /// <field name="unread" type="Boolean">
    /// </field>
    this.id = Formulas.get_newId();
    this.byId = Master.profile.get_myId();
    this.blob = blobIn;
    this.createTime = new Date().getTime();
    this.unread = true;
}
CommentItem.prototype = {
    id: null,
    byId: null,
    blob: null,
    hasComments: false,
    createTime: 0,
    unread: false
}


////////////////////////////////////////////////////////////////////////////////
// ImageItem

ImageItem = function ImageItem() {
    /// <field name="path" type="String">
    /// </field>
    /// <field name="master" type="String">
    /// </field>
    /// <field name="source" type="String">
    /// </field>
    /// <field name="thumb" type="String">
    /// </field>
    /// <field name="width" type="Number" integer="true">
    /// </field>
    /// <field name="height" type="Number" integer="true">
    /// </field>
}
ImageItem.prototype = {
    path: null,
    master: null,
    source: null,
    thumb: null,
    width: 0,
    height: 0
}


////////////////////////////////////////////////////////////////////////////////
// CommentData

CommentData = function CommentData() {
    /// <field name="feedRx" type="String" static="true">
    /// </field>
    /// <field name="_partitionKey$3" type="String" static="true">
    /// </field>
    CommentData.initializeBase(this);
}
CommentData.newGetAw = function CommentData$newGetAw(awp, itemId) {
    /// <param name="awp" type="Await">
    /// </param>
    /// <param name="itemId" type="String">
    /// </param>
    var dta = new CommentData();
    new Await().addAw(ss.Delegate.create(dta, dta.getCommentsAw), itemId).handleDl(Exceptions.blobLoadError, Await.rethrowAw).commit(awp);
}
CommentData.deleteCommentAw = function CommentData$deleteCommentAw(awp, id) {
    /// <param name="awp" type="Await">
    /// </param>
    /// <param name="id" type="String">
    /// </param>
    FileBlobBase.deleteItemAw(awp, CommentData._partitionKey$3, id);
}
CommentData.prototype = {
    
    writeCommentAw: function CommentData$writeCommentAw(awp, itemId, msg) {
        /// <param name="awp" type="Await">
        /// </param>
        /// <param name="itemId" type="String">
        /// </param>
        /// <param name="msg" type="String">
        /// </param>
        ss.Debug.assert(itemId != null, 'WriteCommentAw itemId != null');
        var fd = new CommentItem(msg);
        var rowKey = itemId;
        new Await().addDl(function(aw) {
            FileBlobBase.appendBlobStringAw(aw, CommentData._partitionKey$3, rowKey, 'comment', JSON.stringify(fd));
        }).commit(awp);
    },
    
    getCommentsAw: function CommentData$getCommentsAw(awp, itemId) {
        /// <param name="awp" type="Await">
        /// </param>
        /// <param name="itemId" type="String">
        /// </param>
        var rowKey = itemId;
        new Await().addAw(FileBlobBase.retrieveBlobStringAw, CommentData._partitionKey$3, rowKey).handleDl(Exceptions.blobLoadError, Await.rethrowAw).addDx(function(aw) {
            var content = aw.get_item(PkgBase.resultRx);
            content = FileBlobBase.cleanListData(content);
            awp.set_item(PkgBase.resultRx, (aw.get_item(PkgBase.resultRx) != null) ? JSON.parse('[' + content + ']') : null);
        }).commit(awp);
    }
}


////////////////////////////////////////////////////////////////////////////////
// EyeFocusDropMenu

EyeFocusDropMenu = function EyeFocusDropMenu(el, nameList, handler, eyes) {
    /// <param name="el" type="jQueryObject">
    /// </param>
    /// <param name="nameList" type="Object">
    /// </param>
    /// <param name="handler" type="Nsb.Classes.Function">
    /// </param>
    /// <param name="eyes" type="Eyes">
    /// </param>
    /// <field name="_eyes$1" type="Eyes">
    /// </field>
    EyeFocusDropMenu.initializeBase(this, [ el, nameList, handler ]);
    this._eyes$1 = eyes;
}
EyeFocusDropMenu.prototype = {
    _eyes$1: null,
    
    arrowClick: function EyeFocusDropMenu$arrowClick() {
        this._eyes$1.moveToElement(this.list);
    },
    
    menuHide: function EyeFocusDropMenu$menuHide() {
        this._eyes$1.followMouse();
    }
}


////////////////////////////////////////////////////////////////////////////////
// FeedData

FeedData = function FeedData() {
    /// <field name="feedRx" type="String" static="true">
    /// </field>
    /// <field name="_partitionKey$3" type="String" static="true">
    /// </field>
    /// <field name="_rowKey$3" type="String">
    /// </field>
    /// <field name="feed" type="Array">
    /// </field>
    FeedData.initializeBase(this);
    this._rowKey$3 = Master.profile.get_myId();
}
FeedData.prototype = {
    _rowKey$3: null,
    feed: null,
    
    writeToFeedAw: function FeedData$writeToFeedAw(awp, category, msg) {
        /// <param name="awp" type="Await">
        /// </param>
        /// <param name="category" type="String">
        /// </param>
        /// <param name="msg" type="String">
        /// </param>
        ss.Debug.assert(category != null, 'toId != null');
        var fd = new FeedItem(category, msg);
        Master.profile.addToLocalFeed(fd);
        new Await().addDl(ss.Delegate.create(this, function(aw) {
            FileBlobBase.appendBlobStringAw(aw, FeedData._partitionKey$3, this._rowKey$3, 'feed', JSON.stringify(fd));
        })).commit(awp);
    },
    
    getFeedAw: function FeedData$getFeedAw(awp) {
        /// <param name="awp" type="Await">
        /// </param>
        new Await().addAw(FileBlobBase.retrieveBlobStringAw, FeedData._partitionKey$3, this._rowKey$3).handleDl(Exceptions.blobLoadError, Await.rethrowAw).addDx(ss.Delegate.create(this, function(aw) {
            var content = FileBlobBase.cleanListData(aw.get_item(PkgBase.resultRx));
            this.feed = ((aw.get_item(PkgBase.resultRx) != null) ? JSON.parse('[' + content + ']') : null);
        })).commit(awp);
    },
    
    saveFeedAw: function FeedData$saveFeedAw(awp) {
        /// <param name="awp" type="Await">
        /// </param>
        if (this.feed != null) {
            new Await().addDl(ss.Delegate.create(this, function(aw) {
                FileBlobBase.storeBlobStringAw(aw, { partitionKey: FeedData._partitionKey$3, rowKey: this._rowKey$3, rxKey: 'feed', content: FileBlobBase.simpleList(this.feed) });
            })).commit(awp);
        }
        else {
            awp.done();
        }
    },
    
    addToLocalFeed: function FeedData$addToLocalFeed(item) {
        /// <param name="item" type="FeedItem">
        /// </param>
        if (this.feed != null) {
            this.feed.add(item);
        }
    },
    
    deleteItem: function FeedData$deleteItem(itemId) {
        /// <param name="itemId" type="String">
        /// </param>
        if (this.feed == null) {
            return;
        }
        var cnt = 0;
        var $enum1 = ss.IEnumerator.getEnumerator(this.feed);
        while ($enum1.moveNext()) {
            var i = $enum1.current;
            if (i.id === itemId) {
                this.feed.removeAt(cnt);
                CommentData.deleteCommentAw(Await.get_asyncAw(), i.id);
                this.saveFeedAw(Await.get_asyncAw());
                break;
            }
            cnt++;
        }
    }
}


////////////////////////////////////////////////////////////////////////////////
// GodMode

GodMode = function GodMode() {
    GodMode.initializeBase(this);
}
GodMode.prototype = {
    
    awEv: function GodMode$awEv(awp, e) {
        /// <param name="awp" type="Await">
        /// </param>
        /// <param name="e" type="jQueryEvent">
        /// </param>
        DomElement.cancelEvent(e);
        var gm = Nsb.Storage.getLocal('GodMode');
        Nsb.Storage.setLocal('GodMode', !gm);
        ThemeBase.godMode = !gm;
        this.okAw(awp, { Msg: String.format("Turning God mode \"<span style='color:#009'>{0}</span>\"", (gm) ? 'off' : 'on'), Customize: ss.Delegate.create(this, this.customStuff) });
    },
    
    customStuff: function GodMode$customStuff() {
        var log = Nsb.Storage.getLocal('ErrorLog');
        if (ss.isValue(log)) {
            $('<button/>').appendTo($('.Content', this.element)).html('Obliviate log').click(function() {
                Nsb.Storage.removeLocal('ErrorLog');
                Cluster.flashWindow();
            });
            var ot = '';
            var $enum1 = ss.IEnumerator.getEnumerator(log);
            while ($enum1.moveNext()) {
                var i = $enum1.current;
                i.time = new Date(i.time).format('ddd yyyy-MM-dd hh:mm:ss:fff');
                ot += Rx.prettyJson(i).replace(/^{\s*|\s*}$/g, '') + '\n\n';
            }
            $("<div class='Log'/>").appendTo($('.Content', this.element)).html(Transform.htmlize(ot)).hide();
            $("<span class='Shower' style='cursor:pointer'/>").appendTo($('.Content', this.element)).html('show log').click(ss.Delegate.create(this, function() {
                $('.Shower', this.element).remove();
                $('.Log', this.element).slideDown();
            }));
        }
    }
}


////////////////////////////////////////////////////////////////////////////////
// Yoshi.Classes.ErrorLogItem

Yoshi.Classes.ErrorLogItem = function Yoshi_Classes_ErrorLogItem() {
    /// <field name="line" type="Number" integer="true">
    /// </field>
    /// <field name="msg" type="String">
    /// </field>
    /// <field name="time" type="Number" integer="true">
    /// </field>
    /// <field name="url" type="String">
    /// </field>
}
Yoshi.Classes.ErrorLogItem.prototype = {
    line: 0,
    msg: null,
    time: 0,
    url: null
}


////////////////////////////////////////////////////////////////////////////////
// Help

Help = function Help(domAnchor) {
    /// <param name="domAnchor" type="jQueryObject">
    /// </param>
    /// <field name="_domAnchor$1" type="jQueryObject">
    /// </field>
    /// <field name="message" type="String">
    /// </field>
    /// <field name="_actor$1" type="Actor">
    /// </field>
    Help.initializeBase(this);
    this._domAnchor$1 = domAnchor;
}
Help.prototype = {
    _domAnchor$1: null,
    message: null,
    _actor$1: null,
    
    isAlive: function Help$isAlive() {
        /// <returns type="Boolean"></returns>
        return this._domAnchor$1.is(':visible');
    },
    
    when: function Help$when(test, template) {
        /// <param name="test" type="Function">
        /// </param>
        /// <param name="template" type="Object">
        /// </param>
        /// <returns type="Help"></returns>
        return this.addDl(ss.Delegate.create(this, function() {
            var tmr = 0;
            tmr = this.awaitTimer.setInterval(ss.Delegate.create(this, function() {
                if (this.isAlive()) {
                    if (test()) {
                        window.clearInterval(tmr);
                        if (typeof(template) === 'function') {
                            var fn = template;
                            fn();
                        }
                        else {
                            this._genTemplate$1(template);
                        }
                        this.done();
                    }
                }
                else {
                    window.clearInterval(tmr);
                }
            }), 13);
        }));
    },
    
    after: function Help$after(time, template) {
        /// <param name="time" type="Number" integer="true">
        /// </param>
        /// <param name="template" type="Object">
        /// </param>
        /// <returns type="Help"></returns>
        return this.sleep(time).addDl(ss.Delegate.create(this, function() {
            if (this.isAlive()) {
                if (typeof(template) === 'function') {
                    var fn = template;
                    fn();
                }
                else {
                    this._genTemplate$1(template);
                }
            }
            this.done();
        }));
    },
    
    every: function Help$every(time, template) {
        /// <param name="time" type="Number" integer="true">
        /// </param>
        /// <param name="template" type="Object">
        /// </param>
        /// <returns type="Help"></returns>
        return this.addDl(ss.Delegate.create(this, function() {
            var tmr = 0;
            tmr = this.awaitTimer.setInterval(ss.Delegate.create(this, function() {
                if (this.isAlive()) {
                    if (typeof(template) === 'function') {
                        var fn = template;
                        fn();
                    }
                    else {
                        this._genTemplate$1(template);
                    }
                }
                else {
                    window.clearInterval(tmr);
                }
            }), time);
            this.done();
        }));
    },
    
    _genTemplate$1: function Help$_genTemplate$1(template) {
        /// <param name="template" type="Object">
        /// </param>
        if (this._actor$1 != null) {
            this.destroy();
        }
        this._actor$1 = new Actor();
        var help = $("<div class='HelpBubble HelpZee'/>").appendTo(document.body).addClass(template['class']).html(template['message'] || this.message);
        $("<img class='LightBulb'/>").appendTo(help).attr('src', Uri.join(ThemeBase.mediaImgUri, 'Common/LightBulb.png'));
        this._actor$1.element = help;
        var p = this._domAnchor$1.position();
        help.css({ top: p.top - this._actor$1.element.outerHeight() + parseInt(this._actor$1.element.css('padding-top')), left: p.left + this._domAnchor$1.outerWidth() - this._actor$1.element.outerWidth() - 20 });
        this._actor$1.slideInAw(Await.get_asyncAw());
        if (Object.keyExists(template, 'duration')) {
            this.awaitTimer.setTimeout(ss.Delegate.create(this, this.hide), template['duration']);
        }
    },
    
    reset: function Help$reset() {
        this.destroy();
        this.commit();
    },
    
    hide: function Help$hide() {
        if (this._actor$1 != null) {
            var el = this._actor$1.element;
            this._actor$1 = null;
            el.fadeOut(600, function() {
                el.remove();
            });
        }
    },
    
    autoDestory: function Help$autoDestory() {
        if (!this.isAlive()) {
            this.destroy();
        }
        else {
            window.setTimeout(ss.Delegate.create(this, this.autoDestory), 13);
        }
    },
    
    destroy: function Help$destroy() {
        this.awaitTimer.clearAll();
        this.hide();
    },
    
    commit: function Help$commit() {
        /// <returns type="Await"></returns>
        this.autoDestory();
        return Help.callBaseMethod(this, 'commit');
    }
}


////////////////////////////////////////////////////////////////////////////////
// ProfileTruple

ProfileTruple = function ProfileTruple() {
    ProfileTruple.initializeBase(this);
}
ProfileTruple.prototype = {
    
    playAlias: function ProfileTruple$playAlias(options) {
        /// <param name="options" type="Object">
        /// </param>
        /// <returns type="Nsb.Classes.Truple"></returns>
        var validate = options == null || options['Validate'] == null || options['Validate'];
        var alias = this.input('alias').subHtml('.Label', "Your Play Alias <span style='font-size:70%'>(Required)</span>");
        alias.inputElement().blur(ss.Delegate.create(this, function(e) {
            this.playAliasValidate(e, validate);
        }));
        if (options != null) {
            alias.setOptions(options);
        }
        return alias;
    },
    
    playAliasValidate: function ProfileTruple$playAliasValidate(e, validate) {
        /// <param name="e" type="jQueryEvent">
        /// </param>
        /// <param name="validate" type="Boolean">
        /// </param>
        /// <returns type="Boolean"></returns>
        var ie = Cluster.truples['alias'].inputElement().getFValueString();
        if (validate && (String.isNullOrEmpty(ie) || ie.length < 5)) {
            DomElement.cancelEvent(e);
            new Await().addAw(ss.Delegate.create(new Ask(), new Ask().okAw), 'Play Alias with 5 or more characters is required').addDx(function() {
                Cluster.truples['alias'].inputElement().focus().click();
            }).commit();
            return false;
        }
        return true;
    }
}


////////////////////////////////////////////////////////////////////////////////
// RecordStore

RecordStore = function RecordStore() {
    /// <summary>
    /// Case insensitive record manager
    /// </summary>
}
RecordStore.prototype = {
    
    getRecord: function RecordStore$getRecord(db, key, name, aw) {
        /// <param name="db" type="Object">
        /// </param>
        /// <param name="key" type="String">
        /// </param>
        /// <param name="name" type="String">
        /// </param>
        /// <param name="aw" type="Await">
        /// </param>
        Inform.logFn(arguments);
        if (ss.isNullOrUndefined(db)) {
            throw new Error(Exceptions.argumentNull);
        }
        var records = db[key];
        if (ss.isNullOrUndefined(records)) {
            throw new Error(Exceptions.recordNotExists);
        }
        if (ss.isNullOrUndefined(aw)) {
            throw new Error(Exceptions.missingAwaitDoneEr);
        }
        Inform.trace('RecordStore.GetRecord - EOM');
        aw.doneWith('record', records[name.toLowerCase()]);
    },
    
    putRecord: function RecordStore$putRecord(db, key, name, record) {
        /// <param name="db" type="Object">
        /// </param>
        /// <param name="key" type="String">
        /// </param>
        /// <param name="name" type="String">
        /// </param>
        /// <param name="record" type="Object">
        /// </param>
        Inform.logFn(arguments);
        if (ss.isNullOrUndefined(db)) {
            throw new Error(Exceptions.argumentNull);
        }
        var records = db[key];
        if (ss.isValue(records)) {
            records[name.toLowerCase()] = record;
        }
    },
    
    renameRecord: function RecordStore$renameRecord(db, key, oldName, newName) {
        /// <param name="db" type="Object">
        /// </param>
        /// <param name="key" type="String">
        /// </param>
        /// <param name="oldName" type="String">
        /// </param>
        /// <param name="newName" type="String">
        /// </param>
        oldName = oldName.toLowerCase();
        newName = newName.toLowerCase();
        Inform.logFn(arguments);
        if (ss.isNullOrUndefined(db)) {
            throw new Error(Exceptions.argumentNull);
        }
        var records = db[key];
        if (ss.isValue(records)) {
            if ((typeof(records['get_' + oldName]) === 'function')) {
                if ((typeof(records['get_' + newName]) === 'function')) {
                    throw new Error(Exceptions.newRecordExists);
                }
                var old = records[oldName];
                records[newName] = old;
                delete records[oldName];
            }
            else {
                throw new Error(Exceptions.recordNotExists);
            }
        }
    }
}


////////////////////////////////////////////////////////////////////////////////
// ProfileData

ProfileData = function ProfileData() {
    /// <field name="_profilePartitionKey$3" type="String" static="true">
    /// </field>
    /// <field name="_userCache" type="Object" static="true">
    /// </field>
    /// <field name="_profileRowKey$3" type="String">
    /// </field>
    /// <field name="feedData" type="FeedData">
    /// </field>
    /// <field name="_yoshiUser$3" type="YoshiUser">
    /// </field>
    ProfileData.initializeBase(this);
}
ProfileData.loadMyProfileAw = function ProfileData$loadMyProfileAw(awp) {
    /// <param name="awp" type="Await">
    /// </param>
    var myId = Master.profile.get_myId();
    var data = Master.profile;
    var usr = ProfileData.getUserFromCacheById(myId);
    if (usr != null) {
        data.set_my(usr);
        awp.done();
        return;
    }
    new Await().addAw(ProfileData.loadProfileByIdAw, myId).handleDl(Exceptions.blobLoadError, function(aw) {
        usr = new YoshiUser();
        $.extend(true, usr, Master.fbUser);
        ProfileData._userCache[myId] = usr;
        data.set_my(usr);
        data.saved(false);
        aw.finish();
        awp.handle(new Error(Exceptions.newUser));
    }).addDx(function() {
        data.set_my(ProfileData.getUserFromCacheById(myId));
        if (String.isNullOrEmpty(data.get_my().photo)) {
            data.get_my().photo = Master.fbUser.get_photoUrl();
            data.saved(false);
            data.saveMyProfileAsync(Await.get_asyncAw(), PkgBase.resultRx);
        }
        else {
            data.saved(true);
        }
    }).commit(awp);
}
ProfileData.getUserByIdAw = function ProfileData$getUserByIdAw(awp, id) {
    /// <param name="awp" type="Await">
    /// </param>
    /// <param name="id" type="String">
    /// </param>
    new Await().addDx(function(aw) {
        var usr = ProfileData.getUserFromCacheById(id);
        if (usr != null) {
            awp.set_item(PkgBase.resultRx, usr);
            aw.finish();
        }
    }).addAw(ProfileData.loadProfileByIdAw, id).commit(awp);
}
ProfileData.getUserFromCacheById = function ProfileData$getUserFromCacheById(id) {
    /// <param name="id" type="String">
    /// </param>
    /// <returns type="YoshiUser"></returns>
    return ProfileData._userCache[id];
}
ProfileData.loadProfileByIdAw = function ProfileData$loadProfileByIdAw(awp, id) {
    /// <param name="awp" type="Await">
    /// </param>
    /// <param name="id" type="String">
    /// </param>
    var rowKey = id;
    new Await().addDl(function(aw) {
        FileBlobBase.retrieveBlobAw(aw, ProfileData._profilePartitionKey$3, rowKey);
    }).handleDl(Exceptions.blobLoadError, Await.rethrowAw).addDx(function(aw) {
        var usr = aw.get_item(PkgBase.resultRx);
        if (ss.isValue(usr)) {
            var u = new YoshiUser();
            $.extend(u, usr);
            ProfileData._userCache[id] = u;
            aw.set_item(PkgBase.resultRx, u);
        }
    }).commit(awp);
}
ProfileData.searchForUsersAw = function ProfileData$searchForUsersAw(awp, attributes) {
    /// <param name="awp" type="Await">
    /// </param>
    /// <param name="attributes" type="Object">
    /// </param>
    new Await().addAw(FileBlobBase.getDirAw, Uri.dbPath('profile')).handleDl(Exceptions.blobLoadError, Await.rethrowAw).addDx(function(aw) {
        var result = aw.get_item(PkgBase.resultRx);
        var files = result['files'];
        var ids = [];
        var $enum1 = ss.IEnumerator.getEnumerator(files);
        while ($enum1.moveNext()) {
            var fi = $enum1.current;
            ids.add(fi.split('.')[0]);
        }
        awp.set_item(PkgBase.resultRx, ids);
    }).commit(awp);
}
ProfileData.prototype = {
    _profileRowKey$3: null,
    feedData: null,
    _yoshiUser$3: null,
    
    get_my: function ProfileData$get_my() {
        /// <value type="YoshiUser"></value>
        return this._yoshiUser$3 || (this._yoshiUser$3 = new YoshiUser());
    },
    set_my: function ProfileData$set_my(value) {
        /// <value type="YoshiUser"></value>
        this.feedData = null;
        this._yoshiUser$3 = value;
        Formulas.newIdPrefix = value.id;
        var fbu = new FbUser();
        $.extend(true, fbu, value);
        Master.fbData.fbBaseUser = Master.fbUser = fbu;
        Master.fbData.fbBaseAuth = new FbAuth();
        Master.fbData.fbBaseAuth.access_token = 'test';
        Master.profile.initialize(value.id);
        return value;
    },
    
    get_myId: function ProfileData$get_myId() {
        /// <value type="String"></value>
        return (String.isNullOrEmpty(this.get_my().id)) ? ((Master.fbUser != null) ? Master.fbUser.id : this.get_my().id) : this.get_my().id;
    },
    
    get_myAlias: function ProfileData$get_myAlias() {
        /// <value type="String"></value>
        return this.get_my().alias;
    },
    set_myAlias: function ProfileData$set_myAlias(value) {
        /// <value type="String"></value>
        this.get_my().alias = value;
        return value;
    },
    
    get_feedList: function ProfileData$get_feedList() {
        /// <summary>
        /// Gets the feed list. Possible null return on empty feed.
        /// </summary>
        /// <value type="Array"></value>
        return (this.feedData == null) ? [] : this.feedData.feed || [];
    },
    
    initialize: function ProfileData$initialize(id) {
        /// <param name="id" type="String">
        /// </param>
        ss.Debug.assert(!String.isNullOrEmpty(id), 'My.id is not null or empty');
        this._profileRowKey$3 = id;
    },
    
    saveMyProfileAsync: function ProfileData$saveMyProfileAsync(awp, rxKey) {
        /// <param name="awp" type="Await">
        /// </param>
        /// <param name="rxKey" type="String">
        /// </param>
        if (!this.saved()) {
            this.saved(true);
            new Await().addDl(ss.Delegate.create(this, function(aw) {
                FileBlobBase.storeBlobAw(aw, ProfileData._profilePartitionKey$3, this._profileRowKey$3, rxKey, this.get_my());
            })).handleDl(Exceptions.blobSaveError, ss.Delegate.create(this, function() {
                this.saved(false);
            })).commit(awp);
        }
    },
    
    getFeedAw: function ProfileData$getFeedAw(awp) {
        /// <param name="awp" type="Await">
        /// </param>
        if (this.feedData == null) {
            this.feedData = new FeedData();
        }
        this.feedData.getFeedAw(awp);
    },
    
    addToLocalFeed: function ProfileData$addToLocalFeed(item) {
        /// <param name="item" type="FeedItem">
        /// </param>
        if (this.feedData != null) {
            this.feedData.addToLocalFeed(item);
        }
    },
    
    writeToFeedAw: function ProfileData$writeToFeedAw(awp, category, msg) {
        /// <param name="awp" type="Await">
        /// </param>
        /// <param name="category" type="String">
        /// </param>
        /// <param name="msg" type="String">
        /// </param>
        new FeedData().writeToFeedAw(awp, category, msg);
    },
    
    saveFeedAw: function ProfileData$saveFeedAw(awp) {
        /// <param name="awp" type="Await">
        /// </param>
        if (this.feedData != null) {
            this.feedData.saveFeedAw(awp);
        }
        else {
            awp.done();
        }
    }
}


////////////////////////////////////////////////////////////////////////////////
// SavableData

SavableData = function SavableData() {
    /// <field name="_saved$2" type="Boolean">
    /// </field>
    SavableData.initializeBase(this);
}
SavableData.prototype = {
    _saved$2: true,
    
    saved: function SavableData$saved(ic) {
        /// <param name="ic" type="Boolean">
        /// </param>
        /// <returns type="Boolean"></returns>
        var sv = this._saved$2;
        if (!ss.isNullOrUndefined(ic)) {
            this._saved$2 = ic;
            if (ic !== sv) {
                this.updatePage();
            }
        }
        return sv;
    },
    
    updatePage: function SavableData$updatePage() {
        var pu = new PageUpdate();
        pu.saved = this.saved();
        Master.page.updatePage(pu);
    }
}


////////////////////////////////////////////////////////////////////////////////
// TestData

TestData = function TestData() {
}
TestData.natalie = function TestData$natalie() {
    /// <returns type="YoshiUser"></returns>
    var user = new YoshiUser();
    user.name = 'Natalie Kinsey';
    user.id = '793889201';
    user.email = 'orangegroveatdawn@gmail.com';
    user.bio = "I woke up this morning feeling whole heartedly excited to play with this new Yes Play! site.  I love feeling the ease and  flow opening with this portal of delicious communication and play!  I love how in the zone this is for my desire to collaborate on the Yes, PLay, Love  dating site and be able share our 'work' easily with others.";
    user.photo = Uri.img('Photos/Natalie.JPG');
    return user;
}
TestData.meg = function TestData$meg() {
    /// <returns type="YoshiUser"></returns>
    var user = new YoshiUser();
    user.name = 'Meg Ryan';
    user.id = 'MegRyan';
    user.email = 'megryan@gmail.com';
    user.bio = "Blond-haired, blue-eyed with an effervescent personality, Meg Ryan graduated from Bethel high school, Bethel in June 1979. Moving to New York, she attended New York University where she majored in journalism. To earn extra money while working on her degree, Meg went into acting using her new name Meg Ryan. In 1981, she had her big screen debut as Candice Bergen's daughter in George Cukor's last film Rich and Famous (1981). She tried out and was cast as Betsy in the day time television soap \"As the World Turns\"";
    user.photo = Uri.img('Photos/Meg-Ryan.jpg');
    return user;
}
TestData.testDataRcvdMail = function TestData$testDataRcvdMail() {
    /// <returns type="System.Collections.Generic.IEnumerable"></returns>
    var u1 = Master.profile.get_my();
    var u2 = TestData.natalie();
    var u3 = TestData.meg();
    var list = [];
    list.add({ alias: 'Meg Ryan', fromId: u3.id, toId: u1.id, email: u3.email, subject: 'Are you free tonight?', message: 'Are you free for dinner at Ruth Chriss in Boston?', createTime: 1000, unread: true });
    list.add({ alias: 'Natalie Kinsey', fromId: u2.id, toId: u1.id, email: u2.email, subject: 'Over the clover', message: 'Over the clover is where you will find the end of the rainbow and the key to my heart.<br>Love<br>Natalie', createTime: 2000 });
    list.add({ alias: 'Natalie Kinsey', fromId: u2.id, toId: u1.id, email: u2.email, subject: 'Hey sug', message: 'When you gonna finish that iPhone bubbly emailer?', createTime: 4000, unread: true });
    list.reverse();
    return list;
}
TestData.testDataSentMail = function TestData$testDataSentMail() {
    /// <returns type="System.Collections.Generic.IEnumerable"></returns>
    var u1 = Master.profile.get_my();
    var u2 = TestData.natalie();
    var list = [];
    list.add({ alias: 'Nathan Bawden', fromId: u1.id, toId: u2.id, email: u1.email, subject: 'About last night ...', message: 'I really loved the way you suggested we run around the house between shows. That was exilerating!!<br>Love<br>Nathan', createTime: 3000 });
    list.reverse();
    return list;
}


////////////////////////////////////////////////////////////////////////////////
// MagneticData

MagneticData = function MagneticData() {
    /// <field name="_partitionKey$3" type="String" static="true">
    /// </field>
    /// <field name="_rowKey$3" type="String">
    /// </field>
    /// <field name="records" type="Object">
    /// </field>
    /// <field name="_record$3" type="MagList">
    /// </field>
    this.records = {};
    MagneticData.initializeBase(this);
    this._rowKey$3 = this.get_my().id;
}
MagneticData.prototype = {
    _rowKey$3: null,
    _record$3: null,
    
    get_dataRecord: function MagneticData$get_dataRecord() {
        /// <value type="MagList"></value>
        return this._record$3;
    },
    
    get_my: function MagneticData$get_my() {
        /// <value type="YoshiUser"></value>
        return Master.profile.get_my();
    },
    
    get_recordName: function MagneticData$get_recordName() {
        /// <value type="String"></value>
        return (ss.isValue(this._record$3)) ? this._record$3.name : null;
    },
    
    nameList: function MagneticData$nameList() {
        /// <returns type="Object"></returns>
        return DropMenu.listify(this.records, function(a, b) {
            return ((a).modified_time < (b).modified_time) ? 1 : -1;
        }, function(d, o) {
            d[(o).name] = new Date((o).modified_time).format('yyyy-MM-dd : ') + (o).name;
        });
    },
    
    loadRecordsAw: function MagneticData$loadRecordsAw(awp) {
        /// <param name="awp" type="Await">
        /// </param>
        new Await().addDl(ss.Delegate.create(this, function(aw) {
            FileBlobBase.retrieveBlobAw(aw, MagneticData._partitionKey$3, this._rowKey$3);
        })).handleDl(Exceptions.blobLoadError, function(aw) {
            Inform.trace('LoadRecordsAw() HandleDl');
            aw.done();
        }).addDx(ss.Delegate.create(this, function(aw) {
            Inform.trace('LoadRecordsAw() 2');
            var records = aw.get_item(PkgBase.resultRx);
            if (ss.isValue(records)) {
                this.records = records;
                this.saved(true);
            }
        })).commit(awp);
    },
    
    saveRecords: function MagneticData$saveRecords() {
        this.saved(true);
        FileBlobBase.storeBlobAw(Await.get_asyncAw(), MagneticData._partitionKey$3, this._rowKey$3, PkgBase.resultRx, this.records);
        this.updatePage();
    },
    
    loadRecord: function MagneticData$loadRecord(name) {
        /// <param name="name" type="String">
        /// </param>
        name = name.toLowerCase();
        this._record$3 = (this.records[name] || new MagList(null, null));
        this.saved(true);
    },
    
    saveRecord: function MagneticData$saveRecord() {
        var list = this._scoopData$3();
        if (ss.isValue(list)) {
            this._record$3 = list;
            this.records[this._record$3.name.toLowerCase()] = this._record$3;
            this.saveRecords();
        }
    },
    
    _scoopData$3: function MagneticData$_scoopData$3() {
        /// <summary>
        /// Scoops the data from the manipulator, usually the UI
        /// </summary>
        /// <returns type="MagList"></returns>
        var magEl = $('.MagName');
        if (magEl.length > 0) {
            var name = magEl.getFValueString();
            if (!String.isNullOrEmpty(name)) {
                var list = new MagList(name, $('#MagList textarea'));
                var now = new Date().getTime();
                list.modified_time = ((this._record$3 != null) ? this._record$3.modified_time : 0 || now);
                list.create_time = ((this._record$3 != null) ? this._record$3.create_time : 0 || now);
                return list;
            }
        }
        return null;
    },
    
    emptyRecord: function MagneticData$emptyRecord() {
        this._record$3 = null;
    },
    
    deleteList: function MagneticData$deleteList(name) {
        /// <param name="name" type="String">
        /// </param>
        name = name.toLowerCase();
        if (Object.keyExists(this.records, name)) {
            delete this.records[name];
            this.saved(true);
            FileBlobBase.storeBlobAw(Await.get_asyncAw(), MagneticData._partitionKey$3, this._rowKey$3, PkgBase.resultRx, this.records);
            this.updatePage();
        }
    }
}


////////////////////////////////////////////////////////////////////////////////
// Master

Master = function Master() {
    /// <field name="fbData" type="FbDataStore" static="true">
    /// </field>
    /// <field name="profile" type="ProfileData" static="true">
    /// </field>
    /// <field name="page" type="IPage" static="true">
    /// </field>
    /// <field name="fbUser" type="FbUser" static="true">
    /// </field>
    /// <field name="_loadRetryKey" type="String" static="true">
    /// </field>
    /// <field name="pageMasterId" type="String" static="true">
    /// </field>
    /// <field name="_lastMouseDn" type="jQueryEvent" static="true">
    /// </field>
    /// <field name="debugExt" type="String" static="true">
    /// </field>
    /// <field name="yoshiFlowCheck" type="String" static="true">
    /// </field>
}
Master.MasterPage = function Master$MasterPage() {
    Master.flops();
    var debugging = false;
    Inform.passExceptions = debugging;
    Inform.tracing = debugging;
    Inform.logActions = debugging;
    Inform.debugging = true;
    ThemeBase.dynamicPaging = Uri.end(window.location.href) === ThemeYoshi.masterPage;
    Nsb.Storage.setLocal(ThemeBase.devServerKey, ThemeBase.devServer);
    Nsb.Storage.setLocal('Debug', true);
    ThemeBase.godMode = Nsb.Storage.getLocal('GodMode');
    FileBlobBase.password = (Nsb.Storage.getLocal(ThemeYoshi.get_curatePasswordKey()) || Nsb.Storage.getLocal(ThemeBase.devPasswordKey));
    Inform.log('MasterPage() Initialization');
    window.onerror = function(msg, url, line) {
        try {
            var ic = ss.isValue(ThemeYoshi.pages.pages[ThemeYoshi.currentPageName]);
            if (!ic) {
                throw new Error('');
            }
        }
        catch ($e1) {
            Nsb.Storage.setSession(ThemeYoshi.pageAttrKey, ThemeYoshi.defaultPageClass);
            Nsb.Storage.setSession(ThemeYoshi.pageNameKey, ThemeYoshi.defaultPageName);
        }
        Nsb.Storage.removeSession(ThemeBase.pageActionKey);
        var m = Master.log(msg, url, line);
        Inform.error('Wow - something went wrong!\n\n{0}', m);
        if (!Nsb.Storage.getLocal('GodMode')) {
            Ask.ok({ Msg: String.format('Wow - something went wrong!<br><br><small>{0}</small><br><br>Press OK to reload the page.', m), Complete: ThemeYoshi.reloadPage });
        }
        return true;
    };
    var dle = Nsb.Storage.getLocal('DataLossError');
    if (!String.isNullOrEmpty(dle) && ThemeBase.devServer) {
        throw new Error(dle);
    }
    if (!ThemeBase.dynamicPaging) {
        Master._initStaticPage();
        return;
    }
    if (Nsb.Storage.getSession('cmdReloadPage')) {
        Nsb.Storage.removeSession('cmdReloadPage');
        ThemeYoshi.reloadPage();
    }
    $("<div id='" + 'PageMaster' + "'/>").appendTo(document.body);
    var pageClass = (Object.keyExists(Uri.queryData, 'pageClass')) ? Uri.queryData['pageClass'] : (Nsb.Storage.getSession(ThemeYoshi.pageAttrKey) || ThemeYoshi.defaultPageClass);
    var pageName = (Object.keyExists(Uri.queryData, 'page')) ? Uri.queryData['page'] : (Nsb.Storage.getSession(ThemeYoshi.pageNameKey) || ThemeYoshi.defaultPageName);
    Master.GoPage(pageClass, pageName);
    Master.addEvents();
}
Master.GoPage = function Master$GoPage(pageClass, pageName) {
    /// <param name="pageClass" type="String">
    /// </param>
    /// <param name="pageName" type="String">
    /// </param>
    new Eyes();
    pageClass = pageClass.trim();
    pageName = pageName || 'Home';
    if (Master.page != null) {
        Master.page.destroy();
    }
    ThemeBase.publishing = Nsb.Storage.getLocal(ThemeYoshi.publishingKey);
    $('#' + 'PageMaster').attr('class', '').empty();
    var awx = new Await();
    var parts = pageClass.split('.');
    var pageLib = Uri.scripts('/' + parts[0] + '.debug' + '.js');
    if (parts.length > 1) {
        awx.loadScript(Uri.versionize(pageLib));
    }
    awx.addDx(function() {
        var pgMaster = $('#' + 'PageMaster');
        Css.resetCss(pgMaster);
        if (!ThemeBase.publishing) {
            pgMaster.hide();
        }
    }).handleDl(Exceptions.blobLoadError, function() {
        if (!Nsb.Storage.getLocal('LoadRetry')) {
            Nsb.Storage.removeLocal('LoadRetry');
            $('<h3/>').html('<center>Unable to load ' + pageLib + '</center>').appendTo(document.body);
        }
        else {
            Nsb.Storage.setLocal('LoadRetry', true);
            Nsb.Storage.removeSession(ThemeYoshi.pageAttrKey);
        }
    }).addFn(Master._initPage, pageClass, pageName).commit();
}
Master._initPage = function Master$_initPage(pageClass, pageName) {
    /// <param name="pageClass" type="String">
    /// </param>
    /// <param name="pageName" type="String">
    /// </param>
    Nsb.Storage.removeLocal('LoadRetry');
    if (pageClass.indexOf('.html') > 0) {
        window.location.href = pageClass + '?u=' + new Date().getTime();
        return;
    }
    ss.Debug.assert(Type.getType(pageClass) != null, String.format('Type.GetType({0}) != null', pageClass));
    if (Type.isClass(Type.getType(pageClass))) {
        Nsb.Storage.setSession(ThemeYoshi.pageAttrKey, pageClass);
        Nsb.Storage.setSession(ThemeYoshi.pageNameKey, pageName);
        ThemeYoshi.currentPageClass = pageClass;
        ThemeYoshi.currentPageName = pageName;
        ThemeYoshi.goPage = Master.GoPage;
        ThemeBase.Update();
        FileBlobBase.svCnt++;
        Master.page = eval('new ' + pageClass + '()');
        Master.metaBarRefresh();
        DomElement.scrollToPosAw(Await.get_asyncAw(), 0);
    }
    else {
        throw new Error(Exceptions.invalidPageException);
    }
}
Master.DoMethod = function Master$DoMethod(name) {
    /// <param name="name" type="String">
    /// </param>
    try {
        var p = name.split('.');
        if (!window[p[0]][p[1]]) {
            throw new Error('Invalid DoMethod ' + name);
        }
        eval(name + '()');
    }
    catch (ex) {
        Inform.error(ex.toString());
        Cluster.flashWindow();
    }
}
Master._initStaticPage = function Master$_initStaticPage() {
    Master.addEvents();
    ThemeYoshi.pageDone = true;
}
Master.log = function Master$log(msg, url, line) {
    /// <param name="msg" type="String">
    /// </param>
    /// <param name="url" type="String">
    /// </param>
    /// <param name="line" type="Number" integer="true">
    /// </param>
    /// <returns type="String"></returns>
    url = url || '';
    line = (ss.isValue(line)) ? line : 0;
    var d = { time: new Date().getTime(), msg: msg, url: url, line: line };
    var log = Nsb.Storage.getLocal('ErrorLog') || [];
    log.add(d);
    Nsb.Storage.setLocal('ErrorLog', log);
    msg = msg + '\n' + Uri.path(url) + ':' + line;
    Inform.error(msg);
    return msg;
}
Master.keysDownEv = function Master$keysDownEv(e) {
    /// <param name="e" type="jQueryEvent">
    /// </param>
    if (e.which === 16) {
        ThemeBase.shiftKey = true;
    }
    else if (e.which === 113) {
        DomElement.trigger('F2Event', e);
        DomElement.cancelEvent(e);
    }
    else if (e.which === 114) {
        DomElement.cancelEvent(e);
        if (Nsb.Storage.getLocal('DevPassword') == null) {
            return;
        }
        new Await().loadScript(Uri.scriptsNd('Scripts/ParseXmlLib.js')).loadScript(Uri.scripts('ParseXml.js')).loadScript(Uri.scripts('Scripts/ParseXmlClean.js')).addDx(function() {
            var opt = new ParseXmlOptions();
            opt.Filter = function(po, cls) {
                if (po.getAttr('id') === 'CurateElement') {
                    return true;
                }
                if ((/\b(Cover|CoverInner)\b/).test(cls)) {
                    return true;
                }
                return false;
            };
            var ot = HtmlEmail.ToEmail($('html').html(), opt);
            $('<div/>').appendTo(document.body).html(Transform.htmlize(ot)).css({ color: 'white' });
            Inform.debug(ot);
        }).commit();
    }
    else if (e.which === 115) {
        if (ThemeBase.devServer) {
            $(document).trigger('MBToggle');
        }
    }
    else if (e.which === 116) {
        Nsb.Storage.removeSession(ThemeBase.pageActionKey);
        ThemeYoshi.setDevRefresh();
        ThemeYoshi.rebuildPackageEv(e);
    }
    else if (e.which === 71 && e.ctrlKey) {
        if (Nsb.Storage.getLocal('DevPassword') != null) {
            new GodMode().awEv(Await.get_asyncAw(), e);
        }
    }
}
Master.keysUpEv = function Master$keysUpEv(e) {
    /// <param name="e" type="jQueryEvent">
    /// </param>
    if (e.which === 16) {
        ThemeBase.shiftKey = false;
    }
}
Master.alivenessCheck = function Master$alivenessCheck(fn) {
    /// <param name="fn" type="Function">
    /// </param>
    new Await().loadScript(Uri.versionize(Master.yoshiFlowCheck)).addDx(function() {
        new AlivenessCheck(fn);
    }).commit();
}
Master.metaBarRefresh = function Master$metaBarRefresh() {
    try {
        MetaCluster.StaticRefresh();
    }
    catch ($e1) {
    }
}
Master.mouseUpEv = function Master$mouseUpEv(e) {
    /// <param name="e" type="jQueryEvent">
    /// </param>
    var selected = DomElement.getSelectedText().trim();
    try {
        if (Master._lastMouseDn != null && e.timeStamp - Master._lastMouseDn.timeStamp > 700 && !e.shiftKey && !e.ctrlKey && !e.altKey && !String.isNullOrEmpty(selected)) {
            AlivenessFeed.captureFeedEv(e);
        }
    }
    catch ($e1) {
    }
}
Master.mouseDnEv = function Master$mouseDnEv(e) {
    /// <param name="e" type="jQueryEvent">
    /// </param>
    Master._lastMouseDn = e;
}
Master.pagesEv = function Master$pagesEv(e) {
    /// <param name="e" type="jQueryEvent">
    /// </param>
    try {
        if (!e.shiftKey && !ThemeYoshi.supressCurateEvents) {
            Pages.Ev(e);
        }
    }
    catch ($e1) {
    }
}
Master.badUrlEv = function Master$badUrlEv(e, url) {
    /// <param name="e" type="jQueryEvent">
    /// </param>
    /// <param name="url" type="String">
    /// </param>
    DomElement.cancelEvent(e);
    Ask.ok(String.format('Unrecognized location "{0}"', (url || '')));
}
Master.addEvents = function Master$addEvents() {
    $(document).bind('keydown.master', Master.keysDownEv).bind('keyup.master', Master.keysUpEv).bind('mouseup.master', Master.mouseUpEv).bind('mousedown.master', Master.mouseDnEv).bind('contextmenu', Master.pagesEv).bind(ThemeYoshi.unknownUrlEv, Master.badUrlEv);
}
Master.flops = function Master$flops() {
    /// <summary>
    /// The relative speed of this computer.
    /// </summary>
    var a = 0;
    var b = 0;
    var y;
    var x = new Date().getTime();
    while ((y = new Date().getTime()) === x) {
        a++;
    }
    while (new Date().getTime() === y) {
        b++;
    }
    if (window.console) console.log('Computer speed clear=' + a + ' flops=' + b);
}


Type.registerNamespace('ThemeChain');

////////////////////////////////////////////////////////////////////////////////
// ThemeYoshi

ThemeYoshi = function ThemeYoshi() {
    /// <field name="_trans$1" type="Number" integer="true" static="true">
    /// </field>
    /// <field name="slideDown" type="Number" integer="true" static="true">
    /// </field>
    /// <field name="slideUp" type="Number" integer="true" static="true">
    /// </field>
    /// <field name="fadeIn" type="Number" integer="true" static="true">
    /// </field>
    /// <field name="fadeOut" type="Number" integer="true" static="true">
    /// </field>
    /// <field name="zIndexHider" type="Number" integer="true" static="true">
    /// </field>
    /// <field name="okBtnFace" type="String" static="true">
    /// </field>
    /// <field name="says" type="String" static="true">
    /// </field>
    /// <field name="forSure" type="String" static="true">
    /// </field>
    /// <field name="unGroupClusterMsg" type="String" static="true">
    /// </field>
    /// <field name="cancelBtnFace" type="String" static="true">
    /// </field>
    /// <field name="alivenessAddBtnFace" type="String" static="true">
    /// </field>
    /// <field name="alivenessEditBtnFace" type="String" static="true">
    /// </field>
    /// <field name="commentAddBtnFace" type="String" static="true">
    /// </field>
    /// <field name="likeBtnTitle" type="String" static="true">
    /// </field>
    /// <field name="commentBtnTitle" type="String" static="true">
    /// </field>
    /// <field name="editBtnTitle" type="String" static="true">
    /// </field>
    /// <field name="streamBtnTitle" type="String" static="true">
    /// </field>
    /// <field name="deleteBtnTitle" type="String" static="true">
    /// </field>
    /// <field name="addNewItemBtnTitle" type="String" static="true">
    /// </field>
    /// <field name="unknownUserPhoto" type="String" static="true">
    /// </field>
    /// <field name="_themeYoshiInitialized$1" type="Boolean" static="true">
    /// </field>
    /// <field name="pages" type="PagesD" static="true">
    /// </field>
    /// <field name="defaultPageCss" type="Object" static="true">
    /// </field>
    /// <field name="escapeOut" type="Boolean" static="true">
    /// </field>
    /// <field name="supressCurateEvents" type="Boolean" static="true">
    /// </field>
    /// <field name="logoImage" type="String" static="true">
    /// </field>
    /// <field name="siteTitle" type="String" static="true">
    /// </field>
    /// <field name="defaultPageClass" type="String" static="true">
    /// </field>
    /// <field name="pageAttrKey" type="String" static="true">
    /// </field>
    /// <field name="pageNameKey" type="String" static="true">
    /// </field>
    /// <field name="defaultPageName" type="String" static="true">
    /// </field>
    /// <field name="adminPageName" type="String" static="true">
    /// </field>
    /// <field name="curatorId" type="String" static="true">
    /// </field>
    /// <field name="imagesPartitionKey" type="String" static="true">
    /// </field>
    /// <field name="imagesRowKey" type="String" static="true">
    /// </field>
    /// <field name="currentPageClass" type="String" static="true">
    /// </field>
    /// <field name="currentPageName" type="String" static="true">
    /// </field>
    /// <field name="bgImgUrl" type="String" static="true">
    /// </field>
    /// <field name="pagesDataPath" type="String" static="true">
    /// </field>
    /// <field name="pagesPartition" type="String" static="true">
    /// </field>
    /// <field name="pagesRowKey" type="String" static="true">
    /// </field>
    /// <field name="goPage" type="System.Action`2" static="true">
    /// </field>
    /// <field name="masterPage" type="String" static="true">
    /// </field>
    /// <field name="masterScripts" type="String" static="true">
    /// </field>
    /// <field name="currentBuildAction" type="String" static="true">
    /// </field>
    /// <field name="currentLoadCss" type="String" static="true">
    /// </field>
    /// <field name="currentLoadLibs" type="String" static="true">
    /// </field>
    /// <field name="publishingKey" type="String" static="true">
    /// </field>
    /// <field name="email" type="String" static="true">
    /// </field>
    /// <field name="userId" type="String" static="true">
    /// </field>
    /// <field name="pageDone" type="Boolean" static="true">
    /// </field>
    /// <field name="supportsAudio" type="Boolean" static="true">
    /// </field>
    /// <field name="unknownUrlEv" type="String" static="true">
    /// </field>
    /// <field name="testUsers" type="Object" static="true">
    /// </field>
    /// <field name="safePageRx" type="RegExp" static="true">
    /// </field>
    ThemeYoshi.initializeBase(this);
}
ThemeYoshi.get_metaBarKey = function ThemeYoshi$get_metaBarKey() {
    /// <value type="String"></value>
    return ThemeBase.get_keyPrefix() + '/MetaBar';
}
ThemeYoshi.get_curatingKey = function ThemeYoshi$get_curatingKey() {
    /// <value type="String"></value>
    return ThemeBase.get_keyPrefix() + '/Curating';
}
ThemeYoshi.get_curatePasswordKey = function ThemeYoshi$get_curatePasswordKey() {
    /// <value type="String"></value>
    return ThemeBase.get_keyPrefix() + '/CuratePassword';
}
ThemeYoshi.reloadPage = function ThemeYoshi$reloadPage() {
    ThemeBase.reloading = true;
    if (!String.isNullOrEmpty(Uri.query(window.location.href))) {
        window.location.href = Uri.path(window.location.href);
    }
    else {
        window.location.reload(true);
    }
}
ThemeYoshi.rebuildPackageEv = function ThemeYoshi$rebuildPackageEv(e) {
    /// <param name="e" type="jQueryEvent">
    /// </param>
    DomElement.cancelEvent(e);
    Nsb.Storage.setLocal(ThemeYoshi.publishingKey, false);
    new Await().addAw(ThemeYoshi.rebuildPackageAw).addDx(function() {
        ThemeYoshi.reloadPage();
    }).commit();
}
ThemeYoshi.rebuildPackageAw = function ThemeYoshi$rebuildPackageAw(awp) {
    /// <param name="awp" type="Await">
    /// </param>
    var url = Uri.scripts(ThemeYoshi.masterScripts + '?minimize=y');
    var pw = Nsb.Storage.getLocal(ThemeBase.devPasswordKey);
    if (pw != null) {
        url = Uri.addPair(url, 'debug', 'y');
        url = Uri.addPair(url, 'password', pw);
    }
    Cluster.spinner(true);
    Uri.bumpVersion();
    new Await().loadScript(Uri.versionize(url)).commit(awp);
}
ThemeYoshi.toPublished = function ThemeYoshi$toPublished(e) {
    /// <param name="e" type="jQueryEvent">
    /// </param>
    DomElement.cancelEvent(e);
    Nsb.Storage.setLocal(ThemeYoshi.get_curatingKey(), false);
    window.location.href = ThemeYoshi.publishedUrl();
}
ThemeYoshi.toPublishedHome = function ThemeYoshi$toPublishedHome(e) {
    /// <param name="e" type="jQueryEvent">
    /// </param>
    DomElement.cancelEvent(e);
    Nsb.Storage.setLocal(ThemeYoshi.get_curatingKey(), false);
    window.location.href = Uri.join('pages', ThemeYoshi.defaultPageName + '.html');
}
ThemeYoshi.baseUrl = function ThemeYoshi$baseUrl() {
    /// <returns type="String"></returns>
    return Uri.front(window.location.href) + '/';
}
ThemeYoshi.publishedUrl = function ThemeYoshi$publishedUrl() {
    /// <returns type="String"></returns>
    return Uri.join('pages', ThemeYoshi.currentPageName + '.html');
}
ThemeYoshi.get_currentPage = function ThemeYoshi$get_currentPage() {
    /// <value type="PageD"></value>
    return ThemeYoshi.pages.pages[ThemeYoshi.currentPageName];
}
ThemeYoshi.get_isAdmin = function ThemeYoshi$get_isAdmin() {
    /// <value type="Boolean"></value>
    try {
        return ThemeYoshi.get_currentPage().Admin;
    }
    catch ($e1) {
        return true;
    }
}
ThemeYoshi.IsCurateUrl = function ThemeYoshi$IsCurateUrl(url) {
    /// <param name="url" type="String">
    /// </param>
    /// <returns type="Boolean"></returns>
    return !url.indexOf(ThemeYoshi.masterPage);
}
ThemeYoshi.localUrl = function ThemeYoshi$localUrl(url) {
    /// <param name="url" type="String">
    /// </param>
    /// <returns type="String"></returns>
    if (!(/^https?:\/\//).test(url)) {
        return url;
    }
    if (!url.indexOf(ThemeYoshi.baseUrl())) {
        return url.substr(ThemeYoshi.baseUrl().length);
    }
    return null;
}
ThemeYoshi.SmartUrl = function ThemeYoshi$SmartUrl(url) {
    /// <param name="url" type="String">
    /// </param>
    /// <returns type="String"></returns>
    try {
        if ((/^www\./i).test(url)) {
            return 'http://' + url;
        }
        if ((/^base:/).test(url)) {
            return url.substr(5).trim();
        }
        if ((/^https?:\/\//i).test(url)) {
            return url;
        }
        if (ThemeYoshi.safePageRx.test(Uri.ext(url))) {
            return url;
        }
        var sn = Strings.safeFileName(url);
        if (ThemeYoshi.pages.pages[sn] != null) {
            return Uri.addPair(ThemeYoshi.masterPage, 'page', sn);
        }
    }
    catch ($e1) {
    }
    $(document).trigger(ThemeYoshi.unknownUrlEv, url);
    return url;
}
ThemeYoshi.UnSmartUrl = function ThemeYoshi$UnSmartUrl(url) {
    /// <param name="url" type="String">
    /// </param>
    /// <returns type="String"></returns>
    try {
        if (ThemeYoshi.IsCurateUrl(url)) {
            return ThemeYoshi.pages.pages[Uri.getValue(url, 'page') || ThemeYoshi.defaultPageName].Face;
        }
        if ((/^https?:\/\//i).test(url)) {
            return url;
        }
        if (ThemeYoshi.safePageRx.test(Uri.ext(url))) {
            return url;
        }
        return url;
    }
    catch ($e1) {
        return url;
    }
}
ThemeYoshi.parseEditToAnchors = function ThemeYoshi$parseEditToAnchors(txt) {
    /// <param name="txt" type="String">
    /// </param>
    /// <returns type="String"></returns>
    return UriParse.parseEditToAnchors(txt);
}
ThemeYoshi.parseAnchorsToEdit = function ThemeYoshi$parseAnchorsToEdit(txt) {
    /// <param name="txt" type="String">
    /// </param>
    /// <returns type="String"></returns>
    return UriParse.parseAnchorsToEdit(txt);
}
ThemeYoshi.setDevRefresh = function ThemeYoshi$setDevRefresh() {
    Nsb.Storage.setLocal('DevRefresh', true);
}
ThemeYoshi.get_consumeDevRefresh = function ThemeYoshi$get_consumeDevRefresh() {
    /// <value type="Boolean"></value>
    var ic = Nsb.Storage.getLocal('DevRefresh');
    Nsb.Storage.setLocal('DevRefresh', false);
    return ic;
}


Type.registerNamespace('Yoshi');

Type.registerNamespace('YoshiBase.Classes');

////////////////////////////////////////////////////////////////////////////////
// YoshiUser

YoshiUser = function YoshiUser() {
    /// <field name="bio" type="String">
    /// </field>
    /// <field name="birthday" type="String">
    /// </field>
    /// <field name="email" type="String">
    /// </field>
    /// <field name="first_name" type="String">
    /// </field>
    /// <field name="gender" type="String">
    /// </field>
    /// <field name="id" type="String">
    /// </field>
    /// <field name="last_name" type="String">
    /// </field>
    /// <field name="link" type="String">
    /// </field>
    /// <field name="photo" type="String">
    /// </field>
    /// <field name="locale" type="String">
    /// </field>
    /// <field name="name" type="String">
    /// </field>
    /// <field name="timezone" type="Number" integer="true">
    /// </field>
    /// <field name="hasComments" type="Boolean">
    /// </field>
    /// <field name="updated_time" type="String">
    /// </field>
    /// <field name="verified" type="Boolean">
    /// </field>
    /// <field name="alias" type="String">
    /// </field>
    /// <field name="physique" type="String">
    /// </field>
    /// <field name="height" type="String">
    /// </field>
    /// <field name="smoker" type="String">
    /// </field>
    /// <field name="emmMessage" type="Boolean">
    /// </field>
    /// <field name="emmComment" type="Boolean">
    /// </field>
    /// <field name="emmLike" type="Boolean">
    /// </field>
}
YoshiUser.prototype = {
    bio: null,
    birthday: null,
    email: null,
    first_name: null,
    gender: null,
    id: null,
    last_name: null,
    link: null,
    photo: null,
    locale: null,
    name: null,
    timezone: 0,
    hasComments: false,
    updated_time: null,
    verified: false,
    alias: null,
    physique: null,
    height: null,
    smoker: null,
    emmMessage: true,
    emmComment: true,
    emmLike: true,
    
    get_photoUrl: function YoshiUser$get_photoUrl() {
        /// <value type="String"></value>
        return (String.isNullOrEmpty(this.photo)) ? 'http://graph.facebook.com/' + this.id + '/picture?type=large' : this.photo;
    }
}


////////////////////////////////////////////////////////////////////////////////
// YoshiAuth

YoshiAuth = function YoshiAuth() {
    /// <field name="access_token" type="String">
    /// </field>
    /// <field name="expires" type="Number" integer="true">
    /// </field>
}
YoshiAuth.prototype = {
    access_token: null,
    expires: 0
}


////////////////////////////////////////////////////////////////////////////////
// YoshiAuthData

YoshiAuthData = function YoshiAuthData() {
    /// <field name="user" type="YoshiUser">
    /// </field>
    /// <field name="auth" type="YoshiAuth">
    /// </field>
}
YoshiAuthData.prototype = {
    user: null,
    auth: null
}


////////////////////////////////////////////////////////////////////////////////
// MagList

MagList = function MagList(listName, els) {
    /// <param name="listName" type="String">
    /// </param>
    /// <param name="els" type="jQueryObject">
    /// </param>
    /// <field name="name" type="String">
    /// </field>
    /// <field name="items" type="Array">
    /// </field>
    /// <field name="create_time" type="Number" integer="true">
    /// </field>
    /// <field name="modified_time" type="Number" integer="true">
    /// </field>
    if (listName == null) {
        return;
    }
    this.items = [];
    this.name = listName;
    var my = this;
    if (ss.isValue(els)) {
        els.each(function() {
            var ln = $(this).val().trim();
            if (!String.isNullOrEmpty(ln)) {
                my.items.add(ln);
            }
        });
    }
}
MagList.prototype = {
    name: null,
    items: null,
    create_time: 0,
    modified_time: 0
}


////////////////////////////////////////////////////////////////////////////////
// PageUpdate

PageUpdate = function PageUpdate() {
    /// <field name="saved" type="Boolean">
    /// </field>
}
PageUpdate.prototype = {
    saved: false
}


////////////////////////////////////////////////////////////////////////////////
// EmailListItem

EmailListItem = function EmailListItem() {
    /// <field name="fromId" type="String">
    /// </field>
    /// <field name="lastId" type="String">
    /// </field>
    /// <field name="fAlias" type="String">
    /// </field>
    /// <field name="lAlias" type="String">
    /// </field>
    /// <field name="peek" type="String">
    /// </field>
    /// <field name="unread" type="Boolean">
    /// </field>
    /// <field name="modifyTime" type="Number" integer="true">
    /// </field>
    this.modifyTime = new Date().getTime();
    this.unread = true;
}
EmailListItem.prototype = {
    fromId: null,
    lastId: null,
    fAlias: null,
    lAlias: null,
    peek: null,
    unread: false,
    modifyTime: 0
}


////////////////////////////////////////////////////////////////////////////////
// EmailItem

EmailItem = function EmailItem() {
    /// <field name="id" type="String">
    /// </field>
    /// <field name="alias" type="String">
    /// </field>
    /// <field name="email" type="String">
    /// </field>
    /// <field name="subject" type="String">
    /// </field>
    /// <field name="message" type="String">
    /// </field>
    /// <field name="fromId" type="String">
    /// </field>
    /// <field name="toId" type="String">
    /// </field>
    /// <field name="createTime" type="Number" integer="true">
    /// </field>
    /// <field name="modifyTime" type="Number" integer="true">
    /// </field>
    /// <field name="unread" type="Boolean">
    /// </field>
}
EmailItem.prototype = {
    id: null,
    alias: null,
    email: null,
    subject: null,
    message: null,
    fromId: null,
    toId: null,
    createTime: 0,
    modifyTime: 0,
    unread: false
}


////////////////////////////////////////////////////////////////////////////////
// Conversation

Conversation = function Conversation() {
    /// <field name="fromId" type="String">
    /// </field>
    /// <field name="toId" type="String">
    /// </field>
    /// <field name="thread" type="Array">
    /// </field>
}
Conversation.dateSort = function Conversation$dateSort(x, y) {
    /// <param name="x" type="EmailItem">
    /// </param>
    /// <param name="y" type="EmailItem">
    /// </param>
    /// <returns type="Number" integer="true"></returns>
    return (x.createTime >= y.createTime) ? 1 : -1;
}
Conversation.prototype = {
    fromId: null,
    toId: null,
    thread: null
}


Type.registerNamespace('Yoshi.Fb');

////////////////////////////////////////////////////////////////////////////////
// FbDataStore

FbDataStore = function FbDataStore() {
    FbDataStore.initializeBase(this);
}
FbDataStore.prototype = {
    
    get_user: function FbDataStore$get_user() {
        /// <value type="FbUser"></value>
        return this.fbBaseUser;
    },
    
    get_auth: function FbDataStore$get_auth() {
        /// <value type="FbAuth"></value>
        return this.fbBaseAuth;
    },
    
    authenticateAw: function FbDataStore$authenticateAw(awp) {
        /// <param name="awp" type="Await">
        /// </param>
        if (!this.get_authenticated()) {
            this.fbAuthenticateAw(awp);
        }
        else {
            awp.done();
        }
    },
    
    retrieveFriends: function Yoshi_Fb_FbDataStore$retrieveFriends(fn) {
        /// <param name="fn" type="Function">
        /// </param>
        if (!ss.isValue(this.get_user())) {
            return;
        }
        this.getCache(this.get_user().id, 'friends', function(fbo) {
            if (ss.isValue(fn)) {
                fn(fbo);
            }
            Inform.log('RetrieveFriends - Friend count = {0}', (fbo).data.length);
        });
    },
    
    retrievePhotos: function Yoshi_Fb_FbDataStore$retrievePhotos(albumName, fn) {
        /// <param name="albumName" type="String">
        /// </param>
        /// <param name="fn" type="Function">
        /// </param>
        if (!ss.isValue(this.get_user())) {
            return;
        }
        this.getCache(this.get_user().id, 'albums', ss.Delegate.create(this, function(fbo) {
            var albums = (fbo).data;
            var albumId = '';
            if (ss.isValue(albums)) {
                var $enum1 = ss.IEnumerator.getEnumerator(albums);
                while ($enum1.moveNext()) {
                    var a = $enum1.current;
                    if (a.name !== albumName) {
                        continue;
                    }
                    albumId = a.id;
                    break;
                }
            }
            this.getCache(albumId, 'photos', function(fbo2) {
                var photos = (fbo2).data;
                if (ss.isValue(fn)) {
                    fn(photos);
                }
            });
        }));
    }
}


////////////////////////////////////////////////////////////////////////////////
// FbFileData

FbFileData = function FbFileData() {
    /// <field name="_password$2" type="String" static="true">
    /// </field>
    FbFileData.initializeBase(this);
}
FbFileData.get__putUrl$2 = function FbFileData$get__putUrl$2() {
    /// <value type="String"></value>
    return Uri.join(ThemeBase.appUri, '/file.put.php');
}
FbFileData.prototype = {
    
    _retrieveBlob: function FbFileData$_retrieveBlob(fn) {
        /// <param name="fn" type="Function">
        /// </param>
        this._retrieveFileBlob$2(fn);
    },
    
    _retrieveFileBlob$2: function FbFileData$_retrieveFileBlob$2(fn) {
        /// <param name="fn" type="Function">
        /// </param>
        var payload = {};
        payload['password'] = 'SuperBaby';
        payload['path'] = Uri.dbPath('');
        payload['file'] = 'FB' + this.fbBaseUser.id + '.json';
        var options = {};
        options.url = Uri.join('/yoshi/', ThemeBase.appUri, '/file.get.php');
        options.data = payload;
        options.dataType = 'jsonp';
        options.type = 'GET';
        options.success = ss.Delegate.create(this, function(fbo, textStatus, request1) {
            var data = this._unpackage$2(fbo.content);
            if (ss.isValue(fn)) {
                fn(data);
            }
        });
        options.error = function(request, textStatus, error) {
            Inform.error('Error saving blob to a file error=' + textStatus + ' : ' + error + ' : ' + request.responseText);
        };
        $.ajax(options);
    },
    
    _saveBlob: function FbFileData$_saveBlob(blob, fn) {
        /// <param name="blob" type="Object">
        /// </param>
        /// <param name="fn" type="Function">
        /// </param>
        this._saveFileBlob$2(blob, fn);
    },
    
    _saveFileBlob$2: function FbFileData$_saveFileBlob$2(blob, fn) {
        /// <param name="blob" type="Object">
        /// </param>
        /// <param name="fn" type="Function">
        /// </param>
        var blob64 = this._repackage$2(blob);
        var payload = {};
        payload['password'] = 'SuperBaby';
        payload['createFile'] = 'true';
        payload['createPath'] = 'true';
        payload['path'] = Uri.dbPath('');
        payload['file'] = 'FB' + this.fbBaseUser.id + '.json';
        payload['content'] = blob64;
        var options = {};
        options.url = FbFileData.get__putUrl$2();
        options.data = payload;
        options.type = 'POST';
        options.success = function(fbo, textStatus, request1) {
            try {
                if (!ss.isValue(fbo) || !fbo.result) {
                    throw new Error(Exceptions.blobSaveError);
                }
            }
            catch ($e1) {
                throw new Error(Exceptions.blobSaveError);
            }
            if (ss.isValue(fn)) {
                fn(fbo);
            }
        };
        options.error = function(request, textStatus, error) {
            Inform.error('Error saving blob to a file error=' + textStatus + ' : ' + error + ' : ' + request);
        };
        $.ajax(options);
    },
    
    _repackage$2: function FbFileData$_repackage$2(blob) {
        /// <param name="blob" type="Object">
        /// </param>
        /// <returns type="String"></returns>
        return this._encode$2(JSON.stringify(blob));
    },
    
    _unpackage$2: function FbFileData$_unpackage$2(s) {
        /// <param name="s" type="String">
        /// </param>
        /// <returns type="Object"></returns>
        if (!String.isNullOrEmpty(s)) {
            return JSON.parse(this._decode$2(s));
        }
        return '';
    },
    
    _encode$2: function FbFileData$_encode$2(s) {
        /// <param name="s" type="String">
        /// </param>
        /// <returns type="String"></returns>
        return Nsb.Encoder.encode64(Nsb.Encoder.lzwEncode(s));
    },
    
    _decode$2: function FbFileData$_decode$2(s) {
        /// <param name="s" type="String">
        /// </param>
        /// <returns type="String"></returns>
        return Nsb.Encoder.lzwDecode(Nsb.Encoder.decode64(s));
    }
}


////////////////////////////////////////////////////////////////////////////////
// FbUser

FbUser = function FbUser() {
    /// <field name="bio" type="String">
    /// </field>
    /// <field name="birthday" type="String">
    /// </field>
    /// <field name="email" type="String">
    /// </field>
    /// <field name="first_name" type="String">
    /// </field>
    /// <field name="gender" type="String">
    /// </field>
    /// <field name="id" type="String">
    /// </field>
    /// <field name="last_name" type="String">
    /// </field>
    /// <field name="link" type="String">
    /// </field>
    /// <field name="locale" type="String">
    /// </field>
    /// <field name="name" type="String">
    /// </field>
    /// <field name="timezone" type="Number" integer="true">
    /// </field>
    /// <field name="updated_time" type="String">
    /// </field>
    /// <field name="verified" type="Boolean">
    /// </field>
    /// <field name="work" type="Array" elementType="FbWork">
    /// </field>
    /// <field name="_fbImgTpl" type="String" static="true">
    /// </field>
}
FbUser.prototype = {
    bio: null,
    birthday: null,
    email: null,
    first_name: null,
    gender: null,
    id: null,
    last_name: null,
    link: null,
    locale: null,
    name: null,
    timezone: 0,
    updated_time: null,
    verified: false,
    work: null,
    
    get_photoUrl: function FbUser$get_photoUrl() {
        /// <value type="String"></value>
        return String.format(FbUser._fbImgTpl, this.id);
    },
    
    get_photoTag: function FbUser$get_photoTag() {
        /// <value type="jQueryObject"></value>
        return $('<img/>').attr('src', this.get_photoUrl());
    }
}


////////////////////////////////////////////////////////////////////////////////
// FbList

FbList = function FbList() {
    /// <field name="id" type="String">
    /// </field>
    /// <field name="list_type" type="String">
    /// </field>
    /// <field name="name" type="String">
    /// </field>
}
FbList.prototype = {
    id: null,
    list_type: null,
    name: null
}


////////////////////////////////////////////////////////////////////////////////
// FbResult

FbResult = function FbResult() {
    /// <field name="data" type="Array" elementType="Object">
    /// </field>
    /// <field name="error" type="FbObjectError">
    /// </field>
    /// <field name="paging" type="FbPaging">
    /// </field>
}
FbResult.prototype = {
    data: null,
    error: null,
    paging: null
}


////////////////////////////////////////////////////////////////////////////////
// FbPaging

FbPaging = function FbPaging() {
    /// <field name="next" type="String">
    /// </field>
    /// <field name="prior" type="String">
    /// </field>
}
FbPaging.prototype = {
    next: null,
    prior: null
}


////////////////////////////////////////////////////////////////////////////////
// FbLimitRequest

FbLimitRequest = function FbLimitRequest() {
    /// <field name="access_token" type="String">
    /// </field>
    /// <field name="limit" type="Number" integer="true">
    /// </field>
    /// <field name="offset" type="Number" integer="true">
    /// </field>
}
FbLimitRequest.prototype = {
    access_token: null,
    limit: 0,
    offset: 0
}


////////////////////////////////////////////////////////////////////////////////
// FbOffsetRequest

FbOffsetRequest = function FbOffsetRequest() {
    /// <field name="access_token" type="String">
    /// </field>
    /// <field name="limit" type="Number" integer="true">
    /// </field>
    /// <field name="offset" type="Number" integer="true">
    /// </field>
}
FbOffsetRequest.prototype = {
    access_token: null,
    limit: 0,
    offset: 0
}


////////////////////////////////////////////////////////////////////////////////
// FbObject

FbObject = function FbObject() {
    /// <field name="error" type="FbObjectError">
    /// </field>
}
FbObject.prototype = {
    error: null
}


////////////////////////////////////////////////////////////////////////////////
// FbObjectError

FbObjectError = function FbObjectError() {
    /// <field name="message" type="String">
    /// </field>
    /// <field name="type" type="String">
    /// </field>
}
FbObjectError.prototype = {
    message: null,
    type: null
}


////////////////////////////////////////////////////////////////////////////////
// FbAuth

FbAuth = function FbAuth() {
    /// <field name="access_token" type="String">
    /// </field>
    /// <field name="expires" type="Number" integer="true">
    /// </field>
}
FbAuth.prototype = {
    access_token: null,
    expires: 0
}


////////////////////////////////////////////////////////////////////////////////
// FbWork

FbWork = function FbWork() {
    /// <field name="employer" type="FbUser">
    /// </field>
}
FbWork.prototype = {
    employer: null
}


////////////////////////////////////////////////////////////////////////////////
// FbAlbum

FbAlbum = function FbAlbum() {
    /// <field name="from" type="FbUser">
    /// </field>
    /// <field name="id" type="String">
    /// </field>
    /// <field name="link" type="String">
    /// </field>
    /// <field name="name" type="String">
    /// </field>
    /// <field name="privacy" type="String">
    /// </field>
    /// <field name="type" type="String">
    /// </field>
}
FbAlbum.prototype = {
    from: null,
    id: null,
    link: null,
    name: null,
    privacy: null,
    type: null
}


////////////////////////////////////////////////////////////////////////////////
// FbPhoto

FbPhoto = function FbPhoto() {
    /// <field name="comments" type="FbComments">
    /// </field>
    /// <field name="created_time" type="String">
    /// </field>
    /// <field name="from" type="FbUser">
    /// </field>
    /// <field name="height" type="Number" integer="true">
    /// </field>
    /// <field name="icon" type="String">
    /// </field>
    /// <field name="id" type="String">
    /// </field>
    /// <field name="images" type="Array" elementType="FbImage">
    /// </field>
    /// <field name="link" type="String">
    /// </field>
    /// <field name="name" type="String">
    /// </field>
    /// <field name="picture" type="String">
    /// </field>
    /// <field name="position" type="Number" integer="true">
    /// </field>
    /// <field name="source" type="String">
    /// </field>
    /// <field name="tags" type="FbTags">
    /// </field>
    /// <field name="updated_time" type="String">
    /// </field>
    /// <field name="width" type="Number" integer="true">
    /// </field>
}
FbPhoto.prototype = {
    comments: null,
    created_time: null,
    from: null,
    height: 0,
    icon: null,
    id: null,
    images: null,
    link: null,
    name: null,
    picture: null,
    position: 0,
    source: null,
    tags: null,
    updated_time: null,
    width: 0
}


////////////////////////////////////////////////////////////////////////////////
// FbTags

FbTags = function FbTags() {
    /// <field name="data" type="Array" elementType="FbTag">
    /// </field>
}
FbTags.prototype = {
    data: null
}


////////////////////////////////////////////////////////////////////////////////
// FbTag

FbTag = function FbTag() {
    /// <field name="created_time" type="String">
    /// </field>
    /// <field name="id" type="String">
    /// </field>
    /// <field name="name" type="String">
    /// </field>
    /// <field name="x" type="Number" integer="true">
    /// </field>
    /// <field name="y" type="Number" integer="true">
    /// </field>
}
FbTag.prototype = {
    created_time: null,
    id: null,
    name: null,
    x: 0,
    y: 0
}


////////////////////////////////////////////////////////////////////////////////
// FbNote

FbNote = function FbNote() {
    /// <field name="created_time" type="String">
    /// </field>
    /// <field name="from" type="FbUser">
    /// </field>
    /// <field name="icon" type="String">
    /// </field>
    /// <field name="id" type="String">
    /// </field>
    /// <field name="message" type="String">
    /// </field>
    /// <field name="subject" type="String">
    /// </field>
    /// <field name="updated_time" type="String">
    /// </field>
}
FbNote.prototype = {
    created_time: null,
    from: null,
    icon: null,
    id: null,
    message: null,
    subject: null,
    updated_time: null
}


////////////////////////////////////////////////////////////////////////////////
// FbImage

FbImage = function FbImage() {
    /// <field name="height" type="Number" integer="true">
    /// </field>
    /// <field name="source" type="String">
    /// </field>
    /// <field name="width" type="Number" integer="true">
    /// </field>
}
FbImage.prototype = {
    height: 0,
    source: null,
    width: 0
}


////////////////////////////////////////////////////////////////////////////////
// FbComments

FbComments = function FbComments() {
    /// <field name="data" type="Array" elementType="FbComment">
    /// </field>
}
FbComments.prototype = {
    data: null
}


////////////////////////////////////////////////////////////////////////////////
// FbComment

FbComment = function FbComment() {
    /// <field name="can_remove" type="Boolean">
    /// </field>
    /// <field name="created_time" type="String">
    /// </field>
    /// <field name="from" type="FbUser">
    /// </field>
    /// <field name="id" type="String">
    /// </field>
    /// <field name="message" type="String">
    /// </field>
}
FbComment.prototype = {
    can_remove: false,
    created_time: null,
    from: null,
    id: null,
    message: null
}


////////////////////////////////////////////////////////////////////////////////
// FbSendStorage

FbSendStorage = function FbSendStorage() {
    /// <field name="access_token" type="String">
    /// </field>
    /// <field name="id" type="String">
    /// </field>
    /// <field name="jsonData" type="String">
    /// </field>
    /// <field name="message" type="String">
    /// </field>
    /// <field name="connection" type="String">
    /// </field>
}
FbSendStorage.prototype = {
    access_token: null,
    id: null,
    jsonData: null,
    message: null,
    connection: null
}


////////////////////////////////////////////////////////////////////////////////
// FbIdentity

FbIdentity = function FbIdentity() {
    /// <field name="_appPath$1" type="String" static="true">
    /// </field>
    /// <field name="_fbScope$1" type="String" static="true">
    /// </field>
    /// <field name="_fbUrlHttp" type="String" static="true">
    /// </field>
    /// <field name="_fbUrlHttps$1" type="String" static="true">
    /// </field>
    /// <field name="_limit$1" type="Number" integer="true" static="true">
    /// </field>
    /// <field name="_fbAuthUrl$1" type="String" static="true">
    /// </field>
    /// <field name="fbBaseAuth" type="FbAuth">
    /// </field>
    /// <field name="fbBaseUser" type="FbUser">
    /// </field>
    /// <field name="_cache$1" type="Object">
    /// </field>
    this._cache$1 = {};
    FbIdentity.initializeBase(this);
}
FbIdentity._onErrorReauthenticateAw$1 = function FbIdentity$_onErrorReauthenticateAw$1(awp, fbo) {
    /// <param name="awp" type="Await">
    /// </param>
    /// <param name="fbo" type="FbObject">
    /// </param>
    if (ss.isValue(fbo)) {
        if (ss.isValue(fbo.error)) {
            if (fbo.error.type === 'OAuthException') {
                Nsb.Storage.setLocal('EntryUrl', window.location.href);
                window.location.href = window.location.protocol + '//' + window.location.host + '/' + FbIdentity._fbAuthUrl$1;
                awp.abort();
                throw new Error('FBDone');
            }
            Inform.error(fbo.error.message);
            awp.handle(new Error('FBError'));
        }
    }
}
FbIdentity._getAuthToken$1 = function FbIdentity$_getAuthToken$1() {
    /// <returns type="FbAuth"></returns>
    var auth = new FbAuth();
    var vars = window.location.search.substr(1);
    if (!String.isNullOrEmpty(vars)) {
        var pairs = vars.split('&');
        var $enum1 = ss.IEnumerator.getEnumerator(pairs);
        while ($enum1.moveNext()) {
            var pair = $enum1.current;
            var nvp = pair.split('=');
            var n = nvp[0];
            var v = nvp[1];
            switch (n) {
                case 'access_token':
                    auth.access_token = v;
                    break;
                case 'expires':
                    var expires = parseInt(v) * 1000;
                    auth.expires = new Date().getTime() + expires;
                    break;
            }
        }
    }
    if (!ss.isNullOrUndefined(auth.access_token)) {
        Nsb.Storage.setLocal('FbAccessToken', auth);
        Inform.log('access_token={0}', auth.access_token);
        Inform.log('expires={0}', new Date(auth.expires));
        var url = window.location.href.split('?')[0];
        if (!String.isNullOrEmpty(url)) {
            window.location.href = url;
            throw new Error('FBDone');
        }
    }
    auth = Nsb.Storage.getLocal('FbAccessToken');
    return (ss.isNullOrUndefined(auth)) ? new FbAuth() : auth;
}
FbIdentity.prototype = {
    fbBaseAuth: null,
    fbBaseUser: null,
    
    setProperty: function FbIdentity$setProperty(name, value) {
        /// <summary>
        /// Use for setting properties while chaining methods.
        /// </summary>
        /// <param name="name" type="String">
        /// property name
        /// </param>
        /// <param name="value" type="String">
        /// property value
        /// </param>
        /// <returns type="FbIdentity"></returns>
        this[name] = value;
        return this;
    },
    
    get_authenticated: function FbIdentity$get_authenticated() {
        /// <value type="Boolean"></value>
        return ss.isValue(this.fbBaseUser);
    },
    
    fbAuthenticateAw: function FbIdentity$fbAuthenticateAw(awp) {
        /// <param name="awp" type="Await">
        /// </param>
        this.fbBaseAuth = FbIdentity._getAuthToken$1();
        var request = {};
        var fbLimitRequest = new FbLimitRequest();
        fbLimitRequest.access_token = this.fbBaseAuth.access_token;
        request.url = 'https://graph.facebook.com' + '/me';
        request.type = 'GET';
        request.dataType = 'jsonp';
        request.data = fbLimitRequest;
        request.success = ss.Delegate.create(this, function(fbo, textStatus, request1) {
            try {
                FbIdentity._onErrorReauthenticateAw$1(awp, fbo);
                this.fbBaseUser = Master.fbUser = new FbUser();
                $.extend(true, this.fbBaseUser, fbo);
                Master.profile.initialize(this.fbBaseUser.id);
                Inform.log(String.format('request.Success : User: {0}', this.fbBaseUser.name));
                awp.done();
            }
            catch (ex) {
                Inform.log(String.format('Facebook authentication failure: {0}', ex));
                awp.handle(new Error(Exceptions.serviceLoginFailure));
            }
        });
        request.error = function() {
            Inform.error('Error sending Facebook authentication request');
            awp.abort();
        };
        $.ajax(request);
    },
    
    post: function FbIdentity$post(id, values, connection, fn) {
        /// <param name="id" type="String">
        /// </param>
        /// <param name="values" type="Object">
        /// </param>
        /// <param name="connection" type="String">
        /// </param>
        /// <param name="fn" type="Function">
        /// </param>
        var ajaxRequest = {};
        ajaxRequest.url = 'https://graph.facebook.com' + '/' + id + ((ss.isValue(connection)) ? '/' + connection : '') + '?access_token=' + this.fbBaseAuth.access_token;
        ajaxRequest.type = 'POST';
        ajaxRequest.dataType = 'html';
        ajaxRequest.data = values;
        ajaxRequest.success = function(fbo, textStatus, request1) {
            if (ss.isValue(fn)) {
                fn(fbo);
            }
        };
        ajaxRequest.error = function(request, textStatus, error) {
            Inform.error(String.format('Error posting to Facebook graph api : {0}', textStatus));
        };
        $.ajax(ajaxRequest);
    },
    
    deleteById: function FbIdentity$deleteById(id, fn) {
        /// <param name="id" type="String">
        /// </param>
        /// <param name="fn" type="Function">
        /// </param>
        var ajaxRequest = {};
        var values = {};
        values['access_token'] = this.fbBaseAuth.access_token;
        values['method'] = 'delete';
        ajaxRequest.url = 'https://graph.facebook.com' + '/' + id;
        ajaxRequest.type = 'POST';
        ajaxRequest.dataType = 'json';
        ajaxRequest.data = values;
        ajaxRequest.success = function(fbo, textStatus, request1) {
            if (ss.isValue(fn)) {
                fn(fbo);
            }
        };
        ajaxRequest.error = function(request, textStatus, error) {
            Inform.error(String.format('Error deleting in Facebook graph api : {0}', textStatus));
        };
        $.ajax(ajaxRequest);
    },
    
    get: function FbIdentity$get(id, connection, fn) {
        /// <param name="id" type="String">
        /// </param>
        /// <param name="connection" type="String">
        /// </param>
        /// <param name="fn" type="Function">
        /// </param>
        var ajaxRequest = {};
        var values = {};
        values['access_token'] = this.fbBaseAuth.access_token;
        values['limit'] = 5000;
        ajaxRequest.url = 'https://graph.facebook.com' + '/' + id + ((ss.isValue(connection)) ? '/' + connection : '');
        ajaxRequest.type = 'GET';
        ajaxRequest.dataType = 'jsonp';
        ajaxRequest.data = values;
        ajaxRequest.success = function(fbo, textStatus, request1) {
            if (ss.isValue(fn)) {
                fn(fbo);
            }
        };
        ajaxRequest.error = function(request, textStatus, error) {
            Inform.error(String.format('Error getting from Facebook graph api : {0}', textStatus));
        };
        $.ajax(ajaxRequest);
    },
    
    getCache: function FbIdentity$getCache(id, connection, fn) {
        /// <param name="id" type="String">
        /// </param>
        /// <param name="connection" type="String">
        /// </param>
        /// <param name="fn" type="Function">
        /// </param>
        var key = id + '/' + connection;
        if (Object.keyExists(this._cache$1, key)) {
            if (ss.isValue(fn)) {
                fn(this._cache$1[key]);
            }
            return;
        }
        this.get(id, connection, ss.Delegate.create(this, function(fbo) {
            this._cache$1[key] = fbo;
            if (ss.isValue(fn)) {
                fn(fbo);
            }
        }));
    }
}


FileManager.registerClass('FileManager');
ImageManager.registerClass('ImageManager', FileBlobBase);
StaticBuild.registerClass('StaticBuild');
UriParse.registerClass('UriParse');
PagesD.registerClass('PagesD');
PageD.registerClass('PageD');
FeedItem.registerClass('FeedItem');
CommentItem.registerClass('CommentItem');
ImageItem.registerClass('ImageItem');
SavableData.registerClass('SavableData', PkgBase);
CommentData.registerClass('CommentData', SavableData);
EyeFocusDropMenu.registerClass('EyeFocusDropMenu', DropMenu);
FeedData.registerClass('FeedData', SavableData);
GodMode.registerClass('GodMode', Ask);
Yoshi.Classes.ErrorLogItem.registerClass('Yoshi.Classes.ErrorLogItem');
Help.registerClass('Help', Await);
ProfileTruple.registerClass('ProfileTruple', Nsb.Classes.Truple);
RecordStore.registerClass('RecordStore');
ProfileData.registerClass('ProfileData', SavableData);
TestData.registerClass('TestData');
MagneticData.registerClass('MagneticData', SavableData);
Master.registerClass('Master');
ThemeYoshi.registerClass('ThemeYoshi', ThemeBase);
YoshiUser.registerClass('YoshiUser');
YoshiAuth.registerClass('YoshiAuth');
YoshiAuthData.registerClass('YoshiAuthData');
MagList.registerClass('MagList');
PageUpdate.registerClass('PageUpdate');
EmailListItem.registerClass('EmailListItem');
EmailItem.registerClass('EmailItem');
Conversation.registerClass('Conversation');
FbIdentity.registerClass('FbIdentity', RecordStore);
FbFileData.registerClass('FbFileData', FbIdentity);
FbDataStore.registerClass('FbDataStore', FbFileData);
FbUser.registerClass('FbUser');
FbList.registerClass('FbList');
FbResult.registerClass('FbResult');
FbPaging.registerClass('FbPaging');
FbLimitRequest.registerClass('FbLimitRequest');
FbOffsetRequest.registerClass('FbOffsetRequest');
FbObject.registerClass('FbObject');
FbObjectError.registerClass('FbObjectError');
FbAuth.registerClass('FbAuth');
FbWork.registerClass('FbWork');
FbAlbum.registerClass('FbAlbum');
FbPhoto.registerClass('FbPhoto');
FbTags.registerClass('FbTags');
FbTag.registerClass('FbTag');
FbNote.registerClass('FbNote');
FbImage.registerClass('FbImage');
FbComments.registerClass('FbComments');
FbComment.registerClass('FbComment');
FbSendStorage.registerClass('FbSendStorage');
UriParse._classActionRx = /method:\s*([a-z\d.]+)/i;
UriParse._unClassActionRx = /javascript:\s*Master.DoMethod\(['"](\w+\.[\w\d]+)['"]\)/;
FeedItem.textCategory = 'text';
CommentData.feedRx = 'comment';
CommentData._partitionKey$3 = Uri.dbPath('comments');
FeedData.feedRx = 'feed';
FeedData._partitionKey$3 = Uri.dbPath('feed');
ProfileData._profilePartitionKey$3 = Uri.dbPath('profile');
ProfileData._userCache = {};
MagneticData._partitionKey$3 = Uri.dbPath('lists');
Master.fbData = new FbDataStore();
Master.profile = new ProfileData();
Master.page = null;
Master.fbUser = null;
Master.pageMasterId = 'PageMaster';
Master._lastMouseDn = null;
Master.debugExt = '.debug';
Master.yoshiFlowCheck = Uri.scripts('YoshiFlowCheck') + '.debug' + '.js';
ThemeYoshi.slideDown = 250;
ThemeYoshi.slideUp = 250;
ThemeYoshi.fadeIn = 250;
ThemeYoshi.fadeOut = 250 - 100;
ThemeYoshi.zIndexHider = 999;
ThemeYoshi.okBtnFace = 'Oh Yea!';
ThemeYoshi.says = '<i>says</i>';
ThemeYoshi.forSure = 'Remove for sure?';
ThemeYoshi.unGroupClusterMsg = 'This group is a cluster and cannot be ungrouped.';
ThemeYoshi.cancelBtnFace = 'Not really';
ThemeYoshi.alivenessAddBtnFace = '&hearts; Add to my aliveness stream!';
ThemeYoshi.alivenessEditBtnFace = ThemeBase.hearts + ' Save aliveness changes <b>' + ThemeBase.smile + '</b>';
ThemeYoshi.commentAddBtnFace = '&clubs; Add this comment';
ThemeYoshi.likeBtnTitle = 'I like this aliveness thought!';
ThemeYoshi.commentBtnTitle = 'Click to add a comment';
ThemeYoshi.editBtnTitle = 'Click to edit this item';
ThemeYoshi.streamBtnTitle = 'Click to add this to your aliveness stream';
ThemeYoshi.deleteBtnTitle = 'Delete';
ThemeYoshi.addNewItemBtnTitle = 'Add a new item';
ThemeYoshi.unknownUserPhoto = Uri.img('Photos/Person.jpg');
ThemeYoshi._themeYoshiInitialized$1 = Helpers.staticInheritClass((ThemeYoshi).get_name(), (ThemeBase).get_name());
ThemeYoshi.pages = null;
ThemeYoshi.defaultPageCss = { background: 'center bottom no-repeat', 'background-image': 'none', 'background-color': '#000', 'min-height': '500px', color: '#DDD' };
ThemeYoshi.escapeOut = false;
ThemeYoshi.supressCurateEvents = false;
ThemeYoshi.logoImage = Uri.img('Common/LOGO1.JPG');
ThemeYoshi.siteTitle = "<span style='color: #3289CE'>Play</span> <span style='color: #000'>Nexus</span><span style='font-family:comic sans ms'>&trade;</span>";
ThemeYoshi.defaultPageClass = 'VirtualPage';
ThemeYoshi.pageAttrKey = 'PageClass';
ThemeYoshi.pageNameKey = 'PageName';
ThemeYoshi.defaultPageName = 'home';
ThemeYoshi.adminPageName = 'admin';
ThemeYoshi.curatorId = 'curator';
ThemeYoshi.imagesPartitionKey = 'pg/images';
ThemeYoshi.imagesRowKey = '@images';
ThemeYoshi.currentPageClass = null;
ThemeYoshi.currentPageName = null;
ThemeYoshi.bgImgUrl = null;
ThemeYoshi.pagesDataPath = null;
ThemeYoshi.pagesPartition = 'pg/gigs';
ThemeYoshi.pagesRowKey = 'Pages';
ThemeYoshi.goPage = null;
ThemeYoshi.masterPage = 'master.html';
ThemeYoshi.masterScripts = 'master.php';
ThemeYoshi.currentBuildAction = null;
ThemeYoshi.currentLoadCss = null;
ThemeYoshi.currentLoadLibs = null;
ThemeYoshi.publishingKey = 'Publishing';
ThemeYoshi.email = '';
ThemeYoshi.userId = '';
ThemeYoshi.pageDone = false;
ThemeYoshi.supportsAudio = !!document.createElement('audio').canPlayType;
ThemeYoshi.unknownUrlEv = 'BadUrl';
ThemeYoshi.testUsers = { '100002776766039': true, TestUser1: true, TestUser2: true, TestUser3: true };
ThemeYoshi.safePageRx = /^\.(html|htm|txt|gif|jpeg|jpg|png)$/;
(function () {
    $.ajax({ type: 'HEAD', url: Uri.app('@MasterVersion.txt'), cache: false, success: function(o, s, xr) {
        var modified = xr.getResponseHeader('Last-Modified');
        if (!String.isNullOrEmpty(modified)) {
            var modtime = new Date(modified).getTime();
            var delta = modtime - window.ScriptVersion;
            Inform.debug('Script modified delta = {0}', delta);
            if (delta > 0) {
                Inform.error('Software out of date. delta={0}', delta);
            }
        }
    }, error: function() {
    } });
})();
FbUser._fbImgTpl = 'http://graph.facebook.com' + '/{0}/picture?type=large';
FbIdentity._fbAuthUrl$1 = '/yoshi/php/fb/' + ((ThemeBase.get_isLocalhost()) ? 'fb.authlcl.php' : 'fb.auth.php') + '?scope=' + 'publish_stream,read_friendlists,email,user_birthday,user_photos,user_about_me,user_notes';
